Compare commits
196 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5275c0916f | |||
| 676aa3c78e | |||
| 4e8a65b5ee | |||
| 329ca0b23f | |||
| 29cb01697a | |||
| e27e7baec9 | |||
| 9cd17a4441 | |||
| 9d371c474a | |||
| 5e54b85fe0 | |||
| 286e32bf4e | |||
| 48dbe28031 | |||
| f95df562f7 | |||
| 1f210bba63 | |||
| 4df77ac774 | |||
| aa151c10e1 | |||
| db5e9e6520 | |||
| f22d51b53e | |||
| 68f9b2a5ff | |||
| 444abf57ff | |||
| ffb6bb679a | |||
| 34773a3b98 | |||
| b2e623a488 | |||
| 0e82edc9ea | |||
| cfa93839df | |||
| 6a8b3960d7 | |||
| 97ccbbd049 | |||
| f4090ece63 | |||
| c7a1f6c72a | |||
| 1a61dc53cc | |||
| cbb6cf9a24 | |||
| 3c46f8e276 | |||
| f56af06140 | |||
| 877c6e1d9d | |||
| 75bf51072a | |||
| d5c22a0c91 | |||
| 5d136fa1b8 | |||
| 05f0c3f111 | |||
| 1935f610d3 | |||
| 6b20cda1c0 | |||
| bbae64f923 | |||
| cb48947e9f | |||
| beec31c9b8 | |||
| 383f5d0943 | |||
| cb682748c7 | |||
| 6cce8230f2 | |||
| 0ca7c332f6 | |||
| 075b041b0d | |||
| 302e59e403 | |||
| 1461f00a84 | |||
| 10f4049e68 | |||
| f1db556598 | |||
| 93299ec7da | |||
| 289d38538a | |||
| 60fde40f58 | |||
| 646848cba1 | |||
| b5d7aa8fa8 | |||
| 6bb3c22bec | |||
| 1fd3b60ba3 | |||
| fe1cbcf6c6 | |||
| 119499afa4 | |||
| c26a042a92 | |||
| 48c33157f4 | |||
| 8c5ba5edf0 | |||
| 3ba51a1085 | |||
| 7fd792ba82 | |||
| 4e1ff07d7f | |||
| 7f992433dc | |||
| 2cb1665e2e | |||
| 862e702b2d | |||
| 2f6ed1b89c | |||
| 489cf3a85c | |||
| 188d775b7f | |||
| ec4df58787 | |||
| 4e1c04f74a | |||
| d042fffe75 | |||
| 2199b8b057 | |||
| 344635c75f | |||
| 41977d6b61 | |||
| ef8bc26474 | |||
| d000925ecb | |||
| b3fd715063 | |||
| 85ccc14549 | |||
| e5f4cd4753 | |||
| 4426dc77dc | |||
| 17f07caf72 | |||
| 420f8d0fcc | |||
| 434942ad29 | |||
| aab859a580 | |||
| f71a5f2174 | |||
| cd30ac1d3d | |||
| f6138f4c4b | |||
| 573fa4f8f9 | |||
| 522f5cf743 | |||
| a0abda9313 | |||
| 8591512800 | |||
| db650e970a | |||
| a5b2eeab5d | |||
| f3f051d17c | |||
| 0451f6aca9 | |||
| 25e7631c09 | |||
| fe1509c94b | |||
| 8b94c01ff6 | |||
| 2ab31a663a | |||
| f6edea8753 | |||
| 00cede3763 | |||
| 79bc33bcb7 | |||
| d08096a934 | |||
| 4e094b791c | |||
| 1817e298b1 | |||
| c54dfbbcda | |||
| afbcf35d1c | |||
| 300ba49e8d | |||
| dae1118bf3 | |||
| ecc537475a | |||
| caef6ad1cd | |||
| ffbfb3b133 | |||
| f979e3c4a7 | |||
| 2d7ff1367e | |||
| a829516a33 | |||
| 86d47c83b4 | |||
| 735acb000e | |||
| 62042cfa33 | |||
| 873929b3f6 | |||
| e52a62e689 | |||
| bafaf8a5ae | |||
| f4ed9a9eac | |||
| 71bf19b21c | |||
| 1181e68f27 | |||
| 0722bdad52 | |||
| 92c88f6c0a | |||
| 67a5f49ba2 | |||
| d715b1d534 | |||
| 23e378f977 | |||
| f27d664f61 | |||
| 16c665d199 | |||
| 0b11b1b1d3 | |||
| e699d2e081 | |||
| 9f25842c79 | |||
| fddca6522e | |||
| df0b06ccb7 | |||
| e9aa4203b5 | |||
| 418e071a8d | |||
| 4ca8ac338e | |||
| acbd1080d5 | |||
| ae62a73b58 | |||
| 95cd09c7f2 | |||
| 0b49dc0398 | |||
| 4b28f9eca5 | |||
| 5a18b3f9fb | |||
| 8b9042e2d6 | |||
| 826b829941 | |||
| a36ed10fe2 | |||
| 8d0d93d10e | |||
| ca537f5e9f | |||
| e0c3592868 | |||
| 3a9750015d | |||
| 38ddf11479 | |||
| 15ee95360f | |||
| 308a45efe0 | |||
| ad060dad81 | |||
| 35139c6d84 | |||
| 942d960a90 | |||
| b4c95e4313 | |||
| 293781079a | |||
| 003120d998 | |||
| 57f84c8e2b | |||
| 231c75715a | |||
| 0a1a08a1a5 | |||
| 775008be48 | |||
| b0937ffe18 | |||
| ea9cc62329 | |||
| f6c59d33bd | |||
| 6725df3d26 | |||
| dfdf23315b | |||
| 3a139fc87a | |||
| 04e3dc9c3e | |||
| ca66c6401c | |||
| 1ca079041f | |||
| e922df7635 | |||
| f30cf20400 | |||
| d4155ff348 | |||
| 75fded07d3 | |||
| 61cddd5ba4 | |||
| 24e9b15e42 | |||
| 9bbaba3f72 | |||
| 8c8218bdd8 | |||
| b8c3b4ce91 | |||
| bf7d057d6e | |||
| c4db1a9a00 | |||
| ecfbbe5219 | |||
| 2620435e92 | |||
| 0886dc1995 | |||
| 9a3d7dd992 | |||
| 6224c9cf75 | |||
| a5e1d0206b | |||
| c5531a5177 |
@@ -2,18 +2,18 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Radio.hpp"
|
||||
#include "DriftingDateTime.h"
|
||||
#include "varicode.h"
|
||||
|
||||
|
||||
const int PACKET_TIMEOUT_SECONDS = 300;
|
||||
|
||||
APRSISClient::APRSISClient(QString host, quint16 port, QObject *parent):
|
||||
QTcpSocket(parent),
|
||||
m_host(host),
|
||||
m_port(port)
|
||||
QTcpSocket(parent)
|
||||
{
|
||||
setServer(host, port);
|
||||
|
||||
connect(&m_timer, &QTimer::timeout, this, &APRSISClient::sendReports);
|
||||
m_timer.setInterval(30*1000); // every 30 seconds
|
||||
m_timer.setInterval(60*1000); // every 60 seconds
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ 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");
|
||||
loginFrame = loginFrame.arg("JS8Call");
|
||||
return loginFrame;
|
||||
}
|
||||
|
||||
@@ -184,39 +184,55 @@ QPair<QString, QString> APRSISClient::grid2aprs(QString grid){
|
||||
};
|
||||
}
|
||||
|
||||
QString APRSISClient::stripSSID(QString call){
|
||||
return QString(call.split("-").first().toUpper());
|
||||
}
|
||||
|
||||
QString APRSISClient::replaceCallsignSuffixWithSSID(QString call, QString base){
|
||||
if(call != base){
|
||||
QRegularExpression re("[/](?<ssid>(P|\\d+))");
|
||||
auto matcher = re.globalMatch(call);
|
||||
if(matcher.hasNext()){
|
||||
auto match = matcher.next();
|
||||
auto ssid = match.captured("ssid");
|
||||
if(ssid == "P"){
|
||||
ssid = "16";
|
||||
}
|
||||
call = base + "-" + ssid;
|
||||
} else {
|
||||
call = base;
|
||||
}
|
||||
}
|
||||
return call;
|
||||
}
|
||||
|
||||
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");
|
||||
auto spotFrame = QString("%1>APRS,%2,TCPIP*:=%3/%4nJS8 %5\n");
|
||||
spotFrame = spotFrame.arg(theircall);
|
||||
spotFrame = spotFrame.arg(m_localCall);
|
||||
spotFrame = spotFrame.arg(stripSSID(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");
|
||||
if(!isPasscodeValid()){
|
||||
return;
|
||||
}
|
||||
|
||||
auto frame = QString("%1>APRS,%2,TCPIP*:%3\n");
|
||||
frame = frame.arg(theircall);
|
||||
frame = frame.arg(m_localCall);
|
||||
frame = frame.arg(stripSSID(m_localCall));
|
||||
frame = frame.arg(payload);
|
||||
enqueueRaw(frame);
|
||||
}
|
||||
|
||||
void APRSISClient::enqueueRaw(QString aprsFrame){
|
||||
m_frameQueue.enqueue(aprsFrame);
|
||||
m_frameQueue.enqueue({ aprsFrame, DriftingDateTime::currentDateTimeUtc() });
|
||||
}
|
||||
|
||||
void APRSISClient::processQueue(bool disconnect){
|
||||
@@ -232,6 +248,7 @@ void APRSISClient::processQueue(bool disconnect){
|
||||
// 4. disconnect
|
||||
|
||||
if(state() != QTcpSocket::ConnectedState){
|
||||
qDebug() << "APRSISClient Connecting:" << m_host << m_port;
|
||||
connectToHost(m_host, m_port);
|
||||
if(!waitForConnected(5000)){
|
||||
qDebug() << "APRSISClient Connection Error:" << errorString();
|
||||
@@ -262,21 +279,34 @@ void APRSISClient::processQueue(bool disconnect){
|
||||
return;
|
||||
}
|
||||
|
||||
while(!m_frameQueue.isEmpty()){
|
||||
QByteArray data = m_frameQueue.head().toLocal8Bit();
|
||||
QQueue<QPair<QString, QDateTime>> delayed;
|
||||
|
||||
while(!m_frameQueue.isEmpty()){
|
||||
auto pair = m_frameQueue.head();
|
||||
auto frame = pair.first;
|
||||
auto timestamp = pair.second;
|
||||
|
||||
// if the packet is older than the timeout, drop it.
|
||||
if(timestamp.secsTo(DriftingDateTime::currentDateTimeUtc()) > PACKET_TIMEOUT_SECONDS){
|
||||
qDebug() << "APRSISClient Packet Timeout:" << frame;
|
||||
m_frameQueue.dequeue();
|
||||
continue;
|
||||
}
|
||||
|
||||
// random delay 25% of the time for throttling (a skip will add 60 seconds to the processing time)
|
||||
if(qrand() % 100 <= 25){
|
||||
qDebug() << "APRSISClient Throttle: Skipping Frame";
|
||||
delayed.enqueue(m_frameQueue.dequeue());
|
||||
continue;
|
||||
}
|
||||
|
||||
QByteArray data = frame.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());
|
||||
|
||||
@@ -291,6 +321,11 @@ void APRSISClient::processQueue(bool disconnect){
|
||||
m_frameQueue.dequeue();
|
||||
}
|
||||
|
||||
// enqueue the delayed frames for later processing
|
||||
while(!delayed.isEmpty()){
|
||||
m_frameQueue.enqueue(delayed.dequeue());
|
||||
}
|
||||
|
||||
if(disconnect){
|
||||
disconnectFromHost();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef APRSISCLIENT_H
|
||||
#define APRSISCLIENT_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QDateTime>
|
||||
#include <QTcpSocket>
|
||||
#include <QQueue>
|
||||
#include <QPair>
|
||||
@@ -15,30 +17,55 @@ public:
|
||||
static QString loginFrame(QString callsign);
|
||||
static QPair<float, float> grid2deg(QString grid);
|
||||
static QPair<QString, QString> grid2aprs(QString grid);
|
||||
static QString stripSSID(QString call);
|
||||
static QString replaceCallsignSuffixWithSSID(QString call, QString base);
|
||||
|
||||
void setLocalStation(QString mycall, QString mygrid){
|
||||
m_localCall = mycall;
|
||||
m_localGrid = mygrid;
|
||||
void setServer(QString host, quint16 port){
|
||||
if(state() == QTcpSocket::ConnectedState){
|
||||
disconnectFromHost();
|
||||
}
|
||||
|
||||
m_host = host;
|
||||
m_port = port;
|
||||
|
||||
qDebug() << "APRSISClient Server Change:" << m_host << m_port;
|
||||
}
|
||||
|
||||
void setPaused(bool paused){
|
||||
m_paused = paused;
|
||||
}
|
||||
|
||||
void setLocalStation(QString mycall, QString mygrid, QString passcode){
|
||||
m_localCall = mycall;
|
||||
m_localGrid = mygrid;
|
||||
m_localPasscode = passcode;
|
||||
}
|
||||
|
||||
bool isPasscodeValid(){ return m_localPasscode == QString::number(hashCallsign(m_localCall)); }
|
||||
|
||||
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); }
|
||||
void sendReports(){
|
||||
if(m_paused) return;
|
||||
|
||||
processQueue(true);
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_localCall;
|
||||
QString m_localGrid;
|
||||
QString m_localPasscode;
|
||||
|
||||
QQueue<QString> m_frameQueue;
|
||||
QQueue<QPair<QString, QDateTime>> m_frameQueue;
|
||||
QString m_host;
|
||||
quint16 m_port;
|
||||
QTimer m_timer;
|
||||
bool m_paused;
|
||||
};
|
||||
|
||||
#endif // APRSISCLIENT_H
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Joe Taylor, K1JT <k1jt@arrl.net>
|
||||
|
||||
See also about.cpp or "Help->About WSJT-X" in the application for
|
||||
details of other contributions.
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
There are some defects remaining in WSJT-X.
|
||||
@@ -9,8 +9,8 @@ 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 js8call "@PROJECT_NAME@")
|
||||
set (CPACK_CREATE_DESKTOP_LINKS js8call)
|
||||
set (CPACK_STRIP_FILES TRUE)
|
||||
|
||||
#
|
||||
@@ -24,27 +24,36 @@ 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:\\JS8Call")
|
||||
|
||||
if(CMAKE_CL_64)
|
||||
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
||||
set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} (Win64)")
|
||||
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
|
||||
else()
|
||||
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
||||
set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
|
||||
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
|
||||
endif()
|
||||
|
||||
# set the install/unistall icon used for the installer itself
|
||||
# There is a bug in NSI that does not handle full unix paths properly.
|
||||
set (CPACK_NSIS_MUI_ICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\wsjtx.ico")
|
||||
set (CPACK_NSIS_MUI_UNIICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\wsjtx.ico")
|
||||
set (CPACK_NSIS_MUI_ICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\js8call.ico")
|
||||
set (CPACK_NSIS_MUI_UNIICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\js8call.ico")
|
||||
# set the package header icon for MUI
|
||||
set (CPACK_PACKAGE_ICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\installer_logo.bmp")
|
||||
# tell cpack to create links to the doc files
|
||||
set (CPACK_NSIS_MENU_LINKS
|
||||
"@PROJECT_MANUAL_DIRECTORY_URL@/@PROJECT_MANUAL@" "@PROJECT_NAME@ Documentation"
|
||||
"@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\\\\js8call.exe")
|
||||
|
||||
set (CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
|
||||
set (CPACK_NSIS_HELP_LINK "@PROJECT_MANUAL_DIRECTORY_URL@/@PROJECT_MANUAL@")
|
||||
set (CPACK_NSIS_HELP_LINK "@PROJECT_HOMEPAGE@")
|
||||
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 "js8call.exe")
|
||||
set (CPACK_NSIS_MODIFY_PATH ON)
|
||||
endif ()
|
||||
|
||||
@@ -57,20 +66,21 @@ endif ()
|
||||
if ("${CPACK_GENERATOR}" STREQUAL "DragNDrop")
|
||||
set (CPACK_DMG_VOLUME_NAME "@PROJECT_NAME@")
|
||||
set (CPACK_DMG_BACKGROUND_IMAGE "@PROJECT_SOURCE_DIR@/icons/Darwin/DragNDrop Background.png")
|
||||
set (CPACK_DMG_DS_STORE "@PROJECT_SOURCE_DIR@/Darwin/wsjtx_DMG.DS_Store")
|
||||
set (CPACK_DMG_DS_STORE "@PROJECT_SOURCE_DIR@/Darwin/js8call_DMG.DS_Store")
|
||||
set (CPACK_BUNDLE_NAME "@WSJTX_BUNDLE_NAME@")
|
||||
set (CPACK_PACKAGE_ICON "@PROJECT_BINARY_DIR@/wsjtx.icns")
|
||||
set (CPACK_BUNDLE_ICON "@PROJECT_BINARY_DIR@/wsjtx.icns")
|
||||
set (CPACK_BUNDLE_STARTUP_COMMAND "@PROJECT_SOURCE_DIR@/Mac-wsjtx-startup.sh")
|
||||
set (CPACK_PACKAGE_ICON "@PROJECT_BINARY_DIR@/js8call.icns")
|
||||
set (CPACK_BUNDLE_ICON "@PROJECT_BINARY_DIR@/js8call.icns")
|
||||
set (CPACK_BUNDLE_STARTUP_COMMAND "@PROJECT_SOURCE_DIR@/Mac-js8call-startup.sh")
|
||||
set (CPACK_PACKAGING_INSTALL_PREFIX "/")
|
||||
endif ()
|
||||
|
||||
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}-@js8call_VERSION@-${CPACK_SYSTEM_NAME}")
|
||||
set (CPACK_SOURCE_PACKAGE_FILE_NAME
|
||||
"${CPACK_PACKAGE_NAME}-@ft8call_VERSION@-Source")
|
||||
"${CPACK_PACKAGE_NAME}-@js8call_VERSION@-Source")
|
||||
|
||||
if (NOT CPACK_WIX_SIZEOF_VOID_P)
|
||||
set (CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
|
||||
|
||||
@@ -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 (js8call C CXX Fortran)
|
||||
|
||||
#
|
||||
# CMake policies
|
||||
@@ -45,80 +45,15 @@ message (STATUS "Building ${CMAKE_PROJECT_NAME}-${wsjtx_VERSION}")
|
||||
#
|
||||
# project information
|
||||
#
|
||||
set (PROJECT_NAME "FT8Call")
|
||||
set (PROJECT_NAME "JS8Call")
|
||||
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_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/)
|
||||
set (PROJECT_SAMPLES_URL http://downloads.sourceforge.net/project/wsjt/)
|
||||
set (PROJECT_SAMPLES_UPLOAD_DEST frs.sourceforge.net:/home/frs/project/wsjt/)
|
||||
set (PROJECT_HOMEPAGE https://groups.io/g/js8call)
|
||||
set (PROJECT_SUMMARY_DESCRIPTION "${PROJECT_NAME} - Digital Modes for Weak Signal Communicaitons in Amateur Radio.")
|
||||
set (PROJECT_DESCRIPTION "${PROJECT_SUMMARY_DESCRIPTION}
|
||||
${PROJECT_NAME} is a computer program designed to facilitate basic amateur
|
||||
radio communication using very weak signals. The first four letters in
|
||||
the program name stand for `(W)eak (S)ignal communication by
|
||||
K1(JT),` while the suffix `-X` indicates that ${PROJECT_NAME} started as
|
||||
an extended and experimental branch of the program
|
||||
WSJT.
|
||||
.
|
||||
${PROJECT_NAME} Version 1.8 offers nine different protocols or modes: FT8,
|
||||
JT4, JT9, JT65, QRA64, ISCAT, MSK144, WSPR, and Echo.
|
||||
The first five are designed for making reliable QSOs under extreme
|
||||
weak-signal conditions. They use nearly identical message structure
|
||||
and source encoding. JT65 and QRA64 were designed for EME
|
||||
(`moonbounce`) on the VHF/UHF bands and have also proven very
|
||||
effective for worldwide QRP communication on the HF bands. QRA64 has
|
||||
a number of advantages over JT65, including better performance on the
|
||||
very weakest signals. We imagine that over time it may replace JT65
|
||||
for EME use. JT9 was originally designed for the LF, MF, and lower HF
|
||||
bands. Its submode JT9A is 2 dB more sensitive than JT65 while using
|
||||
less than 10% of the bandwidth. JT4 offers a wide variety of tone
|
||||
spacings and has proven highly effective for EME on microwave bands up
|
||||
to 24 GHz. These four `slow` modes use one-minute timed sequences
|
||||
of alternating transmission and reception, so a minimal QSO takes four
|
||||
to six minutes — two or three transmissions by each station, one
|
||||
sending in odd UTC minutes and the other even. FT8 is operationally
|
||||
similar but four times faster (15-second T/R sequences) and less
|
||||
sensitive by a few dB. On the HF bands, world-wide QSOs are possible
|
||||
with any of these modes using power levels of a few watts (or even
|
||||
milliwatts) and compromise antennas. On VHF bands and higher, QSOs
|
||||
are possible (by EME and other propagation types) at signal levels 10
|
||||
to 15 dB below those required for CW.
|
||||
.
|
||||
ISCAT, MSK144, and optionally submodes JT9E-H are `fast`
|
||||
protocols designed to take advantage of brief signal enhancements from
|
||||
ionized meteor trails, aircraft scatter, and other types of scatter
|
||||
propagation. These modes use timed sequences of 5, 10, 15, or 30 s
|
||||
duration. User messages are transmitted repeatedly at high rate (up
|
||||
to 250 characters per second, for MSK144) to make good use of the
|
||||
shortest meteor-trail reflections or `pings`. ISCAT uses free-form
|
||||
messages up to 28 characters long, while MSK144 uses the same
|
||||
structured messages as the slow modes and optionally an abbreviated
|
||||
format with hashed callsigns.
|
||||
.
|
||||
WSPR (pronounced `whisper`) stands for (W)eak (S)ignal
|
||||
(P)ropagation (R)eporter. The WSPR protocol was designed for probing
|
||||
potential propagation paths using low-power transmissions. WSPR
|
||||
messages normally carry the transmitting station’s callsign, grid
|
||||
locator, and transmitter power in dBm, and they can be decoded at
|
||||
signal-to-noise ratios as low as -28 dB in a 2500 Hz bandwidth. WSPR
|
||||
users with internet access can automatically upload reception
|
||||
reports to a central database called wsprnet that provides a mapping
|
||||
facility, archival storage, and many other features.
|
||||
.
|
||||
Echo mode allows you to detect and measure your own station's echoes
|
||||
from the moon, even if they are far below the audible threshold.
|
||||
.
|
||||
${PROJECT_NAME} provides spectral displays for receiver passbands as wide as
|
||||
5 kHz, flexible rig control for nearly all modern radios used by
|
||||
amateurs, and a wide variety of special aids such as automatic Doppler
|
||||
tracking for EME QSOs and Echo testing. The program runs equally well
|
||||
on Windows, Macintosh, and Linux systems, and installation packages
|
||||
are available for all three platforms.
|
||||
.
|
||||
Be sure to read the online ${PROJECT_NAME} User's Guide.")
|
||||
${PROJECT_NAME} is a computer program designed to facilitate amateur
|
||||
radio communication using very weak signals.")
|
||||
|
||||
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake/Modules ${CMAKE_MODULE_PATH})
|
||||
|
||||
@@ -159,8 +94,7 @@ option (WSJT_TRACE_CAT "Debugging option that turns on CAT diagnostics.")
|
||||
option (WSJT_TRACE_CAT_POLLS "Debugging option that turns on CAT diagnostics during polling.")
|
||||
option (WSJT_HAMLIB_TRACE "Debugging option that turns on minimal Hamlib internal diagnostics.")
|
||||
option (WSJT_SOFT_KEYING "Apply a ramp to CW keying envelope to reduce transients." ON)
|
||||
option (WSJT_SKIP_MANPAGES "Skip *nix manpage generation.")
|
||||
option (WSJT_GENERATE_DOCS "Generate documentation files." ON)
|
||||
option (WSJT_SKIP_MANPAGES "Skip *nix manpage generation." ON)
|
||||
option (WSJT_RIG_NONE_CAN_SPLIT "Allow split operation with \"None\" as rig.")
|
||||
|
||||
CMAKE_DEPENDENT_OPTION (WSJT_HAMLIB_VERBOSE_TRACE "Debugging option that turns on full Hamlib internal diagnostics." OFF WSJT_HAMLIB_TRACE OFF)
|
||||
@@ -169,7 +103,7 @@ CMAKE_DEPENDENT_OPTION (WSJT_QDEBUG_IN_RELEASE "Leave Qt debugging statements in
|
||||
CMAKE_DEPENDENT_OPTION (WSJT_ENABLE_EXPERIMENTAL_FEATURES "Enable features not fully ready for public releases." ON
|
||||
is_debug_build OFF)
|
||||
CMAKE_DEPENDENT_OPTION (WSJT_CREATE_WINMAIN
|
||||
"The wsjtx target is normally built as GUI executable with a WinMain entry point on Windows,
|
||||
"The target is normally built as GUI executable with a WinMain entry point on Windows,
|
||||
if you want a console application instead then set this option to OFF.
|
||||
|
||||
If you just want to see the debug output from the application then the easiest way is to
|
||||
@@ -249,11 +183,6 @@ set (wsjt_qt_CXXSRCS
|
||||
HintedSpinBox.cpp
|
||||
RestrictedSpinBox.cpp
|
||||
HelpTextWindow.cpp
|
||||
SampleDownloader.cpp
|
||||
SampleDownloader/DirectoryDelegate.cpp
|
||||
SampleDownloader/Directory.cpp
|
||||
SampleDownloader/FileNode.cpp
|
||||
SampleDownloader/RemoteFile.cpp
|
||||
DisplayManual.cpp
|
||||
MultiSettings.cpp
|
||||
MaidenheadLocatorValidator.cpp
|
||||
@@ -268,16 +197,17 @@ set (wsjt_qtmm_CXXSRCS
|
||||
Audio/BWFFile.cpp
|
||||
)
|
||||
|
||||
set (jt9_FSRCS
|
||||
set (js8_FSRCS
|
||||
lib/jt9.f90
|
||||
lib/jt9a.f90
|
||||
)
|
||||
|
||||
set (jt9_CXXSRCS
|
||||
set (js8_CXXSRCS
|
||||
lib/ipcomm.cpp
|
||||
)
|
||||
|
||||
set (wsjtx_CXXSRCS
|
||||
DriftingDateTime.cpp
|
||||
logbook/adif.cpp
|
||||
logbook/countrydat.cpp
|
||||
logbook/countriesworked.cpp
|
||||
@@ -304,7 +234,12 @@ set (wsjtx_CXXSRCS
|
||||
messageaveraging.cpp
|
||||
WsprTxScheduler.cpp
|
||||
varicode.cpp
|
||||
jsc.cpp
|
||||
jsc_list.cpp
|
||||
jsc_map.cpp
|
||||
SelfDestructMessageBox.cpp
|
||||
messagereplydialog.cpp
|
||||
keyeater.cpp
|
||||
APRSISClient.cpp
|
||||
mainwindow.cpp
|
||||
Configuration.cpp
|
||||
@@ -668,32 +603,7 @@ set (wsjtx_UISRCS
|
||||
widegraph.ui
|
||||
logqso.ui
|
||||
Configuration.ui
|
||||
)
|
||||
|
||||
set (UDP_library_CXXSRCS
|
||||
Radio.cpp
|
||||
RadioMetaType.cpp
|
||||
NetworkMessage.cpp
|
||||
MessageServer.cpp
|
||||
)
|
||||
|
||||
set (UDP_library_HEADERS
|
||||
Radio.hpp
|
||||
MessageServer.hpp
|
||||
${PROJECT_BINARY_DIR}/udp_export.h
|
||||
)
|
||||
|
||||
set (message_aggregator_CXXSRCS
|
||||
UDPExamples/MessageAggregator.cpp
|
||||
UDPExamples/MessageAggregatorMainWindow.cpp
|
||||
UDPExamples/DecodesModel.cpp
|
||||
UDPExamples/BeaconsModel.cpp
|
||||
UDPExamples/ClientWidget.cpp
|
||||
MaidenheadLocatorValidator.cpp
|
||||
)
|
||||
|
||||
set (message_aggregator_STYLESHEETS
|
||||
UDPExamples/qss/default.qss
|
||||
messagereplydialog.ui
|
||||
)
|
||||
|
||||
set (qcp_CXXSRCS
|
||||
@@ -704,7 +614,7 @@ set (all_CXXSRCS
|
||||
${wsjt_CXXSRCS}
|
||||
${wsjt_qt_CXXSRCS}
|
||||
${wsjt_qtmm_CXXSRCS}
|
||||
${jt9_CXXSRCS}
|
||||
${js8_CXXSRCS}
|
||||
${wsjtx_CXXSRCS}
|
||||
${qcp_CXXSRCS}
|
||||
)
|
||||
@@ -717,11 +627,8 @@ set (all_C_and_CXXSRCS
|
||||
)
|
||||
|
||||
set (TOP_LEVEL_RESOURCES
|
||||
shortcuts.txt
|
||||
mouse_commands.txt
|
||||
prefixes.txt
|
||||
cty.dat
|
||||
icons/Darwin/wsjtx.iconset/icon_128x128.png
|
||||
icons/Darwin/JS8Call.iconset/icon_128x128.png
|
||||
contrib/gpl-v3-logo.svg
|
||||
artwork/splash.png
|
||||
)
|
||||
@@ -821,6 +728,7 @@ endif (WIN32)
|
||||
#
|
||||
if (APPLE)
|
||||
set (WSJTX_BUNDLE_VERSION ${wsjtx_VERSION})
|
||||
set (CMAKE_INSTALL_PREFIX "/")
|
||||
|
||||
# make sure CMAKE_INSTALL_PREFIX ends in /
|
||||
string (LENGTH "${CMAKE_INSTALL_PREFIX}" LEN)
|
||||
@@ -887,14 +795,6 @@ if (WIN32)
|
||||
find_package (Qt5AxContainer REQUIRED)
|
||||
endif (WIN32)
|
||||
|
||||
#
|
||||
# sub-directories
|
||||
#
|
||||
add_subdirectory (samples)
|
||||
if (WSJT_GENERATE_DOCS)
|
||||
add_subdirectory (doc)
|
||||
endif (WSJT_GENERATE_DOCS)
|
||||
|
||||
|
||||
#
|
||||
# Library building setup
|
||||
@@ -1142,7 +1042,7 @@ if (${OPENMP_FOUND} OR APPLE)
|
||||
if (APPLE)
|
||||
# On Mac we don't have working OpenMP support in the C/C++
|
||||
# compilers so we have to manually set the correct flags to get
|
||||
# OpenMP support in jt9.
|
||||
# OpenMP support in js8.
|
||||
target_compile_options (wsjt_fort_omp
|
||||
PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:Fortran>:-fopenmp> # assumes GNU style Fortran compiler
|
||||
@@ -1168,140 +1068,49 @@ endif (WIN32)
|
||||
add_library (wsjt_qtmm STATIC ${wsjt_qtmm_CXXSRCS} ${wsjt_qtmm_GENUISRCS})
|
||||
target_link_libraries (wsjt_qtmm Qt5::Multimedia)
|
||||
|
||||
add_executable (jt4sim lib/jt4sim.f90 wsjtx.rc)
|
||||
target_link_libraries (jt4sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (jt65sim lib/jt65sim.f90 wsjtx.rc)
|
||||
target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (qra64sim lib/qra/qra64/qra64sim.f90 wsjtx.rc)
|
||||
target_link_libraries (qra64sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (jt49sim lib/jt49sim.f90 wsjtx.rc)
|
||||
target_link_libraries (jt49sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (allsim lib/allsim.f90 wsjtx.rc)
|
||||
target_link_libraries (allsim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (jt65code lib/jt65code.f90 wsjtx.rc)
|
||||
target_link_libraries (jt65code wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (qra64code lib/qra64code.f90 wsjtx.rc)
|
||||
target_link_libraries (qra64code wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (jt9code lib/jt9code.f90 wsjtx.rc)
|
||||
target_link_libraries (jt9code wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (wsprcode lib/wsprcode/wsprcode.f90 lib/wsprcode/nhash.c
|
||||
wsjtx.rc)
|
||||
target_link_libraries (wsprcode wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (wsprd ${wsprd_CSRCS})
|
||||
target_include_directories (wsprd PRIVATE ${FFTW3_INCLUDE_DIRS})
|
||||
target_link_libraries (wsprd ${FFTW3_LIBRARIES})
|
||||
|
||||
add_executable (wsprsim ${wsprsim_CSRCS})
|
||||
|
||||
add_executable (jt4code lib/jt4code.f90 wsjtx.rc)
|
||||
target_link_libraries (jt4code wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (msk144code lib/msk144code.f90 wsjtx.rc)
|
||||
target_link_libraries (msk144code wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (jt65 lib/jt65.f90 lib/jt65_test.f90 wsjtx.rc)
|
||||
target_link_libraries (jt65 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim40 lib/ldpcsim40.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim40 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim120 lib/fsk4hf/ldpcsim120.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim120 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim174 lib/ft8/ldpcsim174.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim144 lib/ldpcsim144.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim144 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim168 lib/fsk4hf/ldpcsim168.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim168 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (fsk4hf lib/fsk4hf/fsk4hf.f90 wsjtx.rc)
|
||||
target_link_libraries (fsk4hf wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ft8code lib/ft8/ft8code.f90 wsjtx.rc)
|
||||
target_link_libraries (ft8code wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ft8sim lib/ft8/ft8sim.f90 wsjtx.rc)
|
||||
target_link_libraries (ft8sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (wsprlfsim lib/fsk4hf/wsprlfsim.f90 wsjtx.rc)
|
||||
target_link_libraries (wsprlfsim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (wspr_fsk8d lib/fsk4hf/wspr_fsk8d.f90 wsjtx.rc)
|
||||
target_link_libraries (wspr_fsk8d wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (wspr_fsk8_sim lib/fsk4hf/wspr_fsk8_sim.f90 wsjtx.rc)
|
||||
target_link_libraries (wspr_fsk8_sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (mskhfsim lib/fsk4hf/mskhfsim.f90 wsjtx.rc)
|
||||
target_link_libraries (mskhfsim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (msk144sd lib/msk144sd.f90 wsjtx.rc)
|
||||
target_link_libraries (msk144sd wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (msk144sim lib/msk144sim.f90 wsjtx.rc)
|
||||
target_link_libraries (msk144sim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (msk144d2 lib/msk144d2.f90 wsjtx.rc)
|
||||
target_link_libraries (msk144d2 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (fmtave lib/fmtave.f90 wsjtx.rc)
|
||||
|
||||
add_executable (fcal lib/fcal.f90 wsjtx.rc)
|
||||
|
||||
add_executable (fmeasure lib/fmeasure.f90 wsjtx.rc)
|
||||
|
||||
add_executable (jt9 ${jt9_FSRCS} ${jt9_CXXSRCS} wsjtx.rc)
|
||||
add_executable (js8 ${js8_FSRCS} ${js8_CXXSRCS} wsjtx.rc)
|
||||
if (${OPENMP_FOUND} OR APPLE)
|
||||
if (APPLE)
|
||||
# On Mac we don't have working OpenMP support in the C/C++
|
||||
# compilers so we have to manually set the correct linking flags
|
||||
# and libraries to get OpenMP support in jt9.
|
||||
set_target_properties (jt9
|
||||
# and libraries to get OpenMP support in js8.
|
||||
set_target_properties (js8
|
||||
PROPERTIES
|
||||
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
|
||||
LINK_LIBRARIES "gomp;gcc_s.1" # assume GNU libgcc OpenMP
|
||||
)
|
||||
target_compile_options (jt9
|
||||
target_compile_options (js8
|
||||
PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:Fortran>:-fopenmp> # assumes GNU style Fortran compiler
|
||||
)
|
||||
else (APPLE)
|
||||
if (OpenMP_C_FLAGS)
|
||||
set_target_properties (jt9
|
||||
set_target_properties (js8
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
|
||||
LINK_FLAGS "${OpenMP_C_FLAGS}"
|
||||
)
|
||||
endif ()
|
||||
set_target_properties (jt9
|
||||
set_target_properties (js8
|
||||
PROPERTIES
|
||||
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
|
||||
)
|
||||
endif (APPLE)
|
||||
if (WIN32)
|
||||
# set_target_properties (jt9 PROPERTIES
|
||||
# set_target_properties (js8 PROPERTIES
|
||||
# LINK_FLAGS -Wl,--stack,16777216
|
||||
# )
|
||||
endif ()
|
||||
target_link_libraries (jt9 wsjt_fort_omp wsjt_cxx Qt5::Core)
|
||||
target_link_libraries (js8 wsjt_fort_omp wsjt_cxx Qt5::Core)
|
||||
else (${OPENMP_FOUND} OR APPLE)
|
||||
target_link_libraries (jt9 wsjt_fort wsjt_cxx Qt5::Core)
|
||||
target_link_libraries (js8 wsjt_fort wsjt_cxx Qt5::Core)
|
||||
endif (${OPENMP_FOUND} OR APPLE)
|
||||
|
||||
# build the main application
|
||||
add_executable (ft8call MACOSX_BUNDLE
|
||||
add_executable (js8call MACOSX_BUNDLE
|
||||
${wsjtx_CXXSRCS}
|
||||
${wsjtx_GENUISRCS}
|
||||
wsjtx.rc
|
||||
@@ -1310,10 +1119,10 @@ add_executable (ft8call MACOSX_BUNDLE
|
||||
)
|
||||
|
||||
if (WSJT_CREATE_WINMAIN)
|
||||
set_target_properties (ft8call PROPERTIES WIN32_EXECUTABLE ON)
|
||||
set_target_properties (js8call PROPERTIES WIN32_EXECUTABLE ON)
|
||||
endif (WSJT_CREATE_WINMAIN)
|
||||
|
||||
set_target_properties (ft8call PROPERTIES
|
||||
set_target_properties (js8call 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,112 +1135,49 @@ set_target_properties (ft8call PROPERTIES
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx"
|
||||
)
|
||||
|
||||
target_include_directories (ft8call PRIVATE ${FFTW3_INCLUDE_DIRS})
|
||||
target_include_directories (js8call 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 (js8call 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 (js8call 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 (js8call PROPERTIES
|
||||
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
|
||||
LINK_FLAGS "${OpenMP_C_FLAGS}"
|
||||
)
|
||||
endif ()
|
||||
set_target_properties (ft8call PROPERTIES
|
||||
set_target_properties (js8call PROPERTIES
|
||||
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
|
||||
)
|
||||
if (WIN32)
|
||||
set_target_properties (ft8call PROPERTIES
|
||||
set_target_properties (js8call 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 (js8call 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})
|
||||
add_library (wsjtx_udp-static STATIC ${UDP_library_CXXSRCS})
|
||||
#target_include_directories (wsjtx_udp
|
||||
# INTERFACE
|
||||
# $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/wsjtx>
|
||||
# )
|
||||
target_include_directories (wsjtx_udp-static
|
||||
INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/wsjtx>
|
||||
)
|
||||
#set_target_properties (wsjtx_udp PROPERTIES
|
||||
# PUBLIC_HEADER "${UDP_library_HEADERS}"
|
||||
# )
|
||||
set_target_properties (wsjtx_udp-static PROPERTIES
|
||||
OUTPUT_NAME wsjtx_udp
|
||||
)
|
||||
target_compile_definitions (wsjtx_udp-static PUBLIC UDP_STATIC_DEFINE)
|
||||
#qt5_use_modules (wsjtx_udp Network)
|
||||
qt5_use_modules (wsjtx_udp-static Network Gui)
|
||||
generate_export_header (wsjtx_udp-static BASE_NAME udp)
|
||||
# if (UNIX)
|
||||
# if (NOT WSJT_SKIP_MANPAGES)
|
||||
# add_subdirectory (manpages)
|
||||
# add_dependencies (js8call manpages)
|
||||
# endif (NOT WSJT_SKIP_MANPAGES)
|
||||
# if (NOT APPLE)
|
||||
# add_subdirectory (debian)
|
||||
# add_dependencies (js8call debian)
|
||||
# endif (NOT APPLE)
|
||||
# endif (UNIX)
|
||||
|
||||
add_executable (udp_daemon UDPExamples/UDPDaemon.cpp UDPExamples/udp_daemon.rc ${WSJTX_ICON_FILE})
|
||||
target_link_libraries (udp_daemon wsjtx_udp-static)
|
||||
|
||||
add_resources (message_aggregator_RESOURCES /qss ${message_aggregator_STYLESHEETS})
|
||||
configure_file (UDPExamples/message_aggregator.qrc.in message_aggregator.qrc @ONLY)
|
||||
qt5_add_resources (message_aggregator_RESOURCES_RCC ${CMAKE_CURRENT_BINARY_DIR}/message_aggregator.qrc)
|
||||
add_executable (message_aggregator
|
||||
${message_aggregator_CXXSRCS}
|
||||
${WSJTX_ICON_FILE}
|
||||
UDPExamples/message_aggregator.rc
|
||||
${message_aggregator_RESOURCES_RCC}
|
||||
)
|
||||
target_link_libraries (message_aggregator Qt5::Widgets wsjtx_udp-static)
|
||||
|
||||
if (WSJT_CREATE_WINMAIN)
|
||||
set_target_properties (message_aggregator PROPERTIES WIN32_EXECUTABLE ON)
|
||||
endif (WSJT_CREATE_WINMAIN)
|
||||
|
||||
if (UNIX)
|
||||
if (NOT WSJT_SKIP_MANPAGES)
|
||||
add_subdirectory (manpages)
|
||||
add_dependencies (ft8call manpages)
|
||||
endif (NOT WSJT_SKIP_MANPAGES)
|
||||
if (NOT APPLE)
|
||||
add_subdirectory (debian)
|
||||
add_dependencies (ft8call debian)
|
||||
endif (NOT APPLE)
|
||||
endif (UNIX)
|
||||
|
||||
#
|
||||
# installation
|
||||
#
|
||||
install (TARGETS ft8call
|
||||
install (TARGETS js8call
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION . COMPONENT runtime
|
||||
)
|
||||
|
||||
# install (TARGETS wsjtx_udp EXPORT udp
|
||||
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wsjtx
|
||||
# )
|
||||
# install (TARGETS wsjtx_udp-static EXPORT udp-static
|
||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# )
|
||||
|
||||
# install (EXPORT udp NAMESPACE wsjtx::
|
||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wsjtx
|
||||
# )
|
||||
# install (EXPORT udp-static NAMESPACE wsjtx::
|
||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wsjtx
|
||||
# )
|
||||
|
||||
install (TARGETS udp_daemon message_aggregator
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
)
|
||||
|
||||
install (TARGETS jt9 ft8code jt65code qra64code qra64sim jt9code jt4code
|
||||
msk144code wsprd wspr_fsk8d fmtave fcal fmeasure
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
install (TARGETS js8 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
)
|
||||
|
||||
@@ -1439,24 +1185,21 @@ install (PROGRAMS
|
||||
${RIGCTL_EXE}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
#COMPONENT runtime
|
||||
RENAME rigctl-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
|
||||
RENAME rigctl-local${CMAKE_EXECUTABLE_SUFFIX}
|
||||
)
|
||||
|
||||
install (PROGRAMS
|
||||
${RIGCTLD_EXE}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
#COMPONENT runtime
|
||||
RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
|
||||
RENAME rigctld-local${CMAKE_EXECUTABLE_SUFFIX}
|
||||
)
|
||||
|
||||
install (FILES
|
||||
README
|
||||
COPYING
|
||||
AUTHORS
|
||||
THANKS
|
||||
NEWS
|
||||
INSTALL
|
||||
BUGS
|
||||
INSTALL-WSJTX
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||
#COMPONENT runtime
|
||||
)
|
||||
@@ -1479,7 +1222,6 @@ if (APPLE)
|
||||
)
|
||||
endif (APPLE)
|
||||
|
||||
|
||||
#
|
||||
# uninstall support
|
||||
#
|
||||
@@ -1504,7 +1246,7 @@ add_custom_target (uninstall
|
||||
# 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
|
||||
add_dependencies(wsjt_qt revisiontag)
|
||||
# add_dependencies(wsjt_qt)
|
||||
|
||||
|
||||
#
|
||||
@@ -1517,18 +1259,25 @@ configure_file (
|
||||
|
||||
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
# install a desktop file so wsjtx appears in the application start
|
||||
# install a desktop file so js8call appears in the application start
|
||||
# menu with an icon
|
||||
install (
|
||||
FILES ft8call.desktop message_aggregator.desktop
|
||||
DESTINATION share/applications
|
||||
FILES js8call.desktop
|
||||
DESTINATION /usr/share/applications
|
||||
#COMPONENT runtime
|
||||
)
|
||||
install (
|
||||
FILES icons/Unix/wsjtx_icon.png
|
||||
DESTINATION share/pixmaps
|
||||
FILES icons/Unix/js8call_icon.png
|
||||
DESTINATION /usr/share/pixmaps
|
||||
#COMPONENT runtime
|
||||
)
|
||||
|
||||
execute_process(COMMAND ln -s /opt/js8call/bin/js8call ljs8call)
|
||||
|
||||
install(FILES
|
||||
${CMAKE_BINARY_DIR}/ljs8call DESTINATION /usr/bin/ RENAME js8call
|
||||
#COMPONENT runtime
|
||||
)
|
||||
endif (NOT WIN32 AND NOT APPLE)
|
||||
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QStandardPaths>
|
||||
#include <QSound>
|
||||
#include <QFont>
|
||||
#include <QFontDialog>
|
||||
#include <QColorDialog>
|
||||
@@ -433,7 +434,7 @@ private:
|
||||
void insert_station ();
|
||||
|
||||
Q_SLOT void on_font_push_button_clicked ();
|
||||
Q_SLOT void on_decoded_text_font_push_button_clicked ();
|
||||
Q_SLOT void on_tableFontButton_clicked();
|
||||
Q_SLOT void on_PTT_port_combo_box_activated (int);
|
||||
Q_SLOT void on_CAT_port_combo_box_activated (int);
|
||||
Q_SLOT void on_CAT_serial_baud_combo_box_currentIndexChanged (int);
|
||||
@@ -454,21 +455,37 @@ private:
|
||||
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_cq_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);
|
||||
Q_SLOT void on_save_path_select_push_button_clicked (bool);
|
||||
Q_SLOT void on_azel_path_select_push_button_clicked (bool);
|
||||
Q_SLOT void on_sound_dm_path_select_push_button_clicked();
|
||||
Q_SLOT void on_sound_dm_path_test_push_button_clicked();
|
||||
Q_SLOT void on_sound_dm_path_reset_push_button_clicked();
|
||||
Q_SLOT void on_sound_am_path_select_push_button_clicked();
|
||||
Q_SLOT void on_sound_am_path_test_push_button_clicked();
|
||||
Q_SLOT void on_sound_am_path_reset_push_button_clicked();
|
||||
Q_SLOT void on_calibration_intercept_spin_box_valueChanged (double);
|
||||
Q_SLOT void on_calibration_slope_ppm_spin_box_valueChanged (double);
|
||||
Q_SLOT void handle_transceiver_update (TransceiverState const&, unsigned sequence_number);
|
||||
Q_SLOT void handle_transceiver_failure (QString const& reason);
|
||||
Q_SLOT void on_pbCQmsg_clicked();
|
||||
Q_SLOT void on_pbMyCall_clicked();
|
||||
Q_SLOT void on_pbTxMsg_clicked();
|
||||
Q_SLOT void on_pbNewDXCC_clicked();
|
||||
Q_SLOT void on_pbNewCall_clicked();
|
||||
Q_SLOT void on_tableBackgroundButton_clicked();
|
||||
Q_SLOT void on_tableSelectedRowBackgroundButton_clicked();
|
||||
Q_SLOT void on_tableForegroundButton_clicked();
|
||||
Q_SLOT void on_rxBackgroundButton_clicked();
|
||||
Q_SLOT void on_rxForegroundButton_clicked();
|
||||
Q_SLOT void on_rxFontButton_clicked();
|
||||
Q_SLOT void on_composeBackgroundButton_clicked();
|
||||
Q_SLOT void on_composeForegroundButton_clicked();
|
||||
Q_SLOT void on_composeFontButton_clicked();
|
||||
Q_SLOT void on_txForegroundButton_clicked();
|
||||
Q_SLOT void on_txFontButton_clicked();
|
||||
|
||||
Q_SLOT void on_cbFox_clicked (bool);
|
||||
Q_SLOT void on_cbHound_clicked (bool);
|
||||
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
|
||||
@@ -499,11 +516,23 @@ private:
|
||||
QDir default_azel_directory_;
|
||||
QDir azel_directory_;
|
||||
|
||||
QString sound_dm_path_; // directed message sound file
|
||||
QString sound_am_path_; // alert message sound file
|
||||
|
||||
QFont font_;
|
||||
QFont next_font_;
|
||||
|
||||
QFont decoded_text_font_;
|
||||
QFont next_decoded_text_font_;
|
||||
QFont table_font_;
|
||||
QFont next_table_font_;
|
||||
|
||||
QFont rx_text_font_;
|
||||
QFont next_rx_text_font_;
|
||||
|
||||
QFont tx_text_font_;
|
||||
QFont next_tx_text_font_;
|
||||
|
||||
QFont compose_text_font_;
|
||||
QFont next_compose_text_font_;
|
||||
|
||||
bool restart_sound_input_device_;
|
||||
bool restart_sound_output_device_;
|
||||
@@ -555,17 +584,33 @@ private:
|
||||
QString my_callsign_;
|
||||
QString my_grid_;
|
||||
QString my_station_;
|
||||
QString aprs_ssid_;
|
||||
QString my_qth_;
|
||||
QString cq_;
|
||||
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_cq_;
|
||||
QColor next_color_cq_;
|
||||
QColor color_mycall_;
|
||||
QColor next_color_mycall_;
|
||||
|
||||
QColor color_table_background_;
|
||||
QColor next_color_table_background_;
|
||||
QColor color_table_highlight_;
|
||||
QColor next_color_table_highlight_;
|
||||
QColor color_table_foreground_;
|
||||
QColor next_color_table_foreground_;
|
||||
|
||||
QColor color_rx_background_;
|
||||
QColor next_color_rx_background_;
|
||||
QColor color_rx_foreground_;
|
||||
QColor next_color_rx_foreground_;
|
||||
QColor color_compose_background_;
|
||||
QColor next_color_compose_background_;
|
||||
QColor color_compose_foreground_;
|
||||
QColor next_color_compose_foreground_;
|
||||
QColor color_tx_foreground_;
|
||||
QColor next_color_tx_foreground_;
|
||||
QColor color_DXCC_;
|
||||
QColor next_color_DXCC_;
|
||||
QColor color_NewCall_;
|
||||
@@ -577,10 +622,12 @@ private:
|
||||
double degrade_;
|
||||
double txDelay_;
|
||||
bool id_after_73_;
|
||||
bool tx_QSY_allowed_;
|
||||
bool tx_qsy_allowed_;
|
||||
bool spot_to_reporting_networks_;
|
||||
bool transmit_directed_;
|
||||
bool autoreply_off_at_startup_;
|
||||
bool beacon_anywhere_;
|
||||
bool relay_disabled_;
|
||||
bool monitor_off_at_startup_;
|
||||
bool monitor_last_used_;
|
||||
bool log_as_DATA_;
|
||||
@@ -606,6 +653,11 @@ private:
|
||||
bool x4ToneSpacing_;
|
||||
bool use_dynamic_info_;
|
||||
QString opCall_;
|
||||
|
||||
QString aprs_server_name_;
|
||||
QString aprs_passcode_;
|
||||
port_type aprs_server_port_;
|
||||
|
||||
QString udp_server_name_;
|
||||
port_type udp_server_port_;
|
||||
// QString n1mm_server_name () const;
|
||||
@@ -665,13 +717,23 @@ bool Configuration::restart_audio_output () const {return m_->restart_sound_outp
|
||||
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_table_background() const { return m_->color_table_background_; }
|
||||
QColor Configuration::color_table_highlight() const { return m_->color_table_highlight_; }
|
||||
QColor Configuration::color_table_foreground() const { return m_->color_table_foreground_; }
|
||||
QColor Configuration::color_CQ () const {return m_->color_cq_;}
|
||||
QColor Configuration::color_MyCall () const {return m_->color_mycall_;}
|
||||
QColor Configuration::color_rx_background () const {return m_->color_rx_background_;}
|
||||
QColor Configuration::color_rx_foreground () const {return m_->color_rx_foreground_;}
|
||||
QColor Configuration::color_tx_foreground () const {return m_->color_tx_foreground_;}
|
||||
QColor Configuration::color_compose_background () const {return m_->color_compose_background_;}
|
||||
QColor Configuration::color_compose_foreground () const {return m_->color_compose_foreground_;}
|
||||
QColor Configuration::color_DXCC () const {return m_->color_DXCC_;}
|
||||
QColor Configuration::color_NewCall () const {return m_->color_NewCall_;}
|
||||
QFont Configuration::table_font () const {return m_->table_font_;}
|
||||
QFont Configuration::text_font () const {return m_->font_;}
|
||||
QFont Configuration::decoded_text_font () const {return m_->decoded_text_font_;}
|
||||
QFont Configuration::rx_text_font () const {return m_->rx_text_font_;}
|
||||
QFont Configuration::tx_text_font () const {return m_->tx_text_font_;}
|
||||
QFont Configuration::compose_text_font () const {return m_->compose_text_font_;}
|
||||
qint32 Configuration::id_interval () const {return m_->id_interval_;}
|
||||
qint32 Configuration::ntrials() const {return m_->ntrials_;}
|
||||
qint32 Configuration::aggressive() const {return m_->aggressive_;}
|
||||
@@ -679,7 +741,7 @@ double Configuration::degrade() const {return m_->degrade_;}
|
||||
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::tx_qsy_allowed () const {return m_->tx_qsy_allowed_;}
|
||||
bool Configuration::spot_to_reporting_networks () const
|
||||
{
|
||||
// rig must be open and working to spot externally
|
||||
@@ -695,6 +757,8 @@ void Configuration::set_spot_to_reporting_networks (bool spot)
|
||||
|
||||
bool Configuration::transmit_directed() const { return m_->transmit_directed_; }
|
||||
bool Configuration::autoreply_off_at_startup () const {return m_->autoreply_off_at_startup_;}
|
||||
bool Configuration::beacon_anywhere() const { return m_->beacon_anywhere_;}
|
||||
bool Configuration::relay_off() const { return m_->relay_disabled_; }
|
||||
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_;}
|
||||
@@ -720,6 +784,9 @@ bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;}
|
||||
bool Configuration::x4ToneSpacing() const {return m_->x4ToneSpacing_;}
|
||||
bool Configuration::split_mode () const {return m_->split_mode ();}
|
||||
QString Configuration::opCall() const {return m_->opCall_;}
|
||||
QString Configuration::aprs_server_name () const {return m_->aprs_server_name_;}
|
||||
auto Configuration::aprs_server_port () const -> port_type {return m_->aprs_server_port_;}
|
||||
QString Configuration::aprs_passcode() const { return m_->aprs_passcode_; }
|
||||
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
|
||||
auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;}
|
||||
bool Configuration::accept_udp_requests () const {return m_->accept_udp_requests_;}
|
||||
@@ -741,6 +808,8 @@ QStringListModel * Configuration::macros () {return &m_->macros_;}
|
||||
QStringListModel const * Configuration::macros () const {return &m_->macros_;}
|
||||
QDir Configuration::save_directory () const {return m_->save_directory_;}
|
||||
QDir Configuration::azel_directory () const {return m_->azel_directory_;}
|
||||
QString Configuration::sound_dm_path() const {return m_->sound_dm_path_;}
|
||||
QString Configuration::sound_am_path() const {return m_->sound_am_path_;}
|
||||
QString Configuration::rig_name () const {return m_->rig_params_.rig_name;}
|
||||
bool Configuration::pwrBandTxMemory () const {return m_->pwrBandTxMemory_;}
|
||||
bool Configuration::pwrBandTuneMemory () const {return m_->pwrBandTuneMemory_;}
|
||||
@@ -865,16 +934,17 @@ QString Configuration::my_station() const
|
||||
return station;
|
||||
}
|
||||
|
||||
QString Configuration::aprs_ssid() const {
|
||||
return m_->aprs_ssid_;
|
||||
}
|
||||
|
||||
QString Configuration::my_qth() const
|
||||
{
|
||||
return m_->my_qth_;
|
||||
}
|
||||
|
||||
QString Configuration::reply() const
|
||||
QString Configuration::cq_message() const
|
||||
{
|
||||
return m_->cq_;
|
||||
}
|
||||
|
||||
QString Configuration::reply_message() const
|
||||
{
|
||||
return m_->reply_;
|
||||
}
|
||||
@@ -1040,6 +1110,7 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
|
||||
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_->cq_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 ());
|
||||
@@ -1230,13 +1301,20 @@ void Configuration::impl::initialize_models ()
|
||||
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_->cq_message_line_edit->setText(cq_.toUpper());
|
||||
ui_->reply_message_line_edit->setText (reply_.toUpper());
|
||||
ui_->use_dynamic_grid->setChecked(use_dynamic_info_);
|
||||
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_->labDXCC->setStyleSheet(QString("background: %1").arg(color_DXCC_.name()));
|
||||
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(color_NewCall_.name()));
|
||||
|
||||
ui_->tableBackgroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_table_background_.name()).arg(next_color_table_foreground_.name()));
|
||||
ui_->tableSelectionBackgroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_table_highlight_.name()).arg(next_color_table_foreground_.name()));
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1; color: %2").arg(next_color_cq_.name()).arg(next_color_table_foreground_.name()));
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1; color: %2").arg(next_color_mycall_.name()).arg(next_color_table_foreground_.name()));
|
||||
|
||||
ui_->rxLabel->setStyleSheet(QString("background: %1; color: %2").arg(color_rx_background_.name()).arg(color_rx_foreground_.name()));
|
||||
ui_->rxForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(color_rx_background_.name()).arg(color_rx_foreground_.name()));
|
||||
ui_->txForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(color_rx_background_.name()).arg(color_tx_foreground_.name()));
|
||||
ui_->composeLabel->setStyleSheet(QString("background: %1; color: %2").arg(color_compose_background_.name()).arg(color_compose_foreground_.name()));
|
||||
|
||||
ui_->CW_id_interval_spin_box->setValue (id_interval_);
|
||||
ui_->sbNtrials->setValue (ntrials_);
|
||||
ui_->sbTxDelay->setValue (txDelay_);
|
||||
@@ -1246,27 +1324,27 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->PTT_method_button_group->button (rig_params_.ptt_type)->setChecked (true);
|
||||
ui_->save_path_display_label->setText (save_directory_.absolutePath ());
|
||||
ui_->azel_path_display_label->setText (azel_directory_.absolutePath ());
|
||||
ui_->sound_dm_path_display_label->setText(sound_dm_path_);
|
||||
ui_->sound_am_path_display_label->setText(sound_am_path_);
|
||||
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
|
||||
ui_->tx_QSY_check_box->setChecked (tx_QSY_allowed_);
|
||||
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_->beacon_anywhere_check_box->setChecked(beacon_anywhere_);
|
||||
ui_->relay_disabled_check_box->setChecked(relay_disabled_);
|
||||
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_->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_);
|
||||
ui_->DXCC_check_box->setChecked (DXCC_);
|
||||
ui_->ppfx_check_box->setChecked (ppfx_);
|
||||
ui_->clear_DX_check_box->setChecked (clear_DX_);
|
||||
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_);
|
||||
ui_->decode_at_52s_check_box->setChecked(decode_at_52s_);
|
||||
ui_->single_decode_check_box->setChecked(single_decode_);
|
||||
@@ -1304,6 +1382,9 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->TX_audio_source_button_group->button (rig_params_.audio_source)->setChecked (true);
|
||||
ui_->CAT_poll_interval_spin_box->setValue (rig_params_.poll_interval);
|
||||
ui_->opCallEntry->setText (opCall_);
|
||||
ui_->aprs_server_line_edit->setText (aprs_server_name_);
|
||||
ui_->aprs_server_port_spin_box->setValue (aprs_server_port_);
|
||||
ui_->aprs_passcode_line_edit->setText(aprs_passcode_);
|
||||
ui_->udp_server_line_edit->setText (udp_server_name_);
|
||||
ui_->udp_server_port_spin_box->setValue (udp_server_port_);
|
||||
ui_->accept_udp_requests_check_box->setChecked (accept_udp_requests_);
|
||||
@@ -1356,38 +1437,87 @@ void Configuration::impl::read_settings ()
|
||||
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();
|
||||
cq_ = settings_->value("CQMessage", QString {"CQCQCQ"}).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_cq_ = color_cq_ = settings_->value("colorCQ","#66ff66").toString();
|
||||
next_color_mycall_ = color_mycall_ = settings_->value("colorMyCall","#ff6666").toString();
|
||||
next_color_rx_background_ = color_rx_background_ = settings_->value("color_rx_background","#ffeaa7").toString();
|
||||
next_color_rx_foreground_ = color_rx_foreground_ = settings_->value("color_rx_foreground","#000000").toString();
|
||||
next_color_compose_background_ = color_compose_background_ = settings_->value("color_compose_background","#ffffff").toString();
|
||||
next_color_compose_foreground_ = color_compose_foreground_ = settings_->value("color_compose_foreground","#000000").toString();
|
||||
next_color_tx_foreground_ = color_tx_foreground_ = settings_->value("color_tx_foreground","#ff0000").toString();
|
||||
next_color_DXCC_ = color_DXCC_ = settings_->value("colorDXCC","#ff00ff").toString();
|
||||
next_color_NewCall_ = color_NewCall_ = settings_->value("colorNewCall","#ffaaff").toString();
|
||||
|
||||
next_color_table_background_ = color_table_background_ = settings_->value("colorTableBackground", "#ffffff").toString();
|
||||
next_color_table_highlight_ = color_table_highlight_ = settings_->value("colorTableHighlight", "#3498db").toString();
|
||||
next_color_table_foreground_ = color_table_foreground_ = settings_->value("colorTableForeground","#000000").toString();
|
||||
|
||||
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_font_ != font_)
|
||||
{
|
||||
font_ = next_font_;
|
||||
Q_EMIT self_->text_font_changed (font_);
|
||||
Q_EMIT self_->gui_text_font_changed (font_);
|
||||
}
|
||||
else
|
||||
{
|
||||
next_font_ = font_;
|
||||
}
|
||||
if (next_decoded_text_font_.fromString (settings_->value ("DecodedTextFont", "Courier, 10").toString ())
|
||||
&& next_decoded_text_font_ != decoded_text_font_)
|
||||
ui_->font_push_button->setText(QString("Application Font (%1 %2)").arg(next_font_.family()).arg(next_font_.pointSize()));
|
||||
|
||||
if (next_tx_text_font_.fromString (settings_->value ("TXTextFont", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_tx_text_font_ != tx_text_font_)
|
||||
{
|
||||
decoded_text_font_ = next_decoded_text_font_;
|
||||
Q_EMIT self_->decoded_text_font_changed (decoded_text_font_);
|
||||
tx_text_font_ = next_tx_text_font_;
|
||||
Q_EMIT self_->tx_text_font_changed (tx_text_font_);
|
||||
}
|
||||
else
|
||||
{
|
||||
next_decoded_text_font_ = decoded_text_font_;
|
||||
next_tx_text_font_ = tx_text_font_;
|
||||
}
|
||||
|
||||
ui_->txFontButton->setText(QString("Font (%1 %2)").arg(next_tx_text_font_.family()).arg(next_tx_text_font_.pointSize()));
|
||||
|
||||
if (next_rx_text_font_.fromString (settings_->value ("RXTextFont", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_rx_text_font_ != rx_text_font_)
|
||||
{
|
||||
rx_text_font_ = next_rx_text_font_;
|
||||
Q_EMIT self_->rx_text_font_changed (rx_text_font_);
|
||||
}
|
||||
else
|
||||
{
|
||||
next_rx_text_font_ = rx_text_font_;
|
||||
}
|
||||
|
||||
ui_->rxFontButton->setText(QString("Font (%1 %2)").arg(next_rx_text_font_.family()).arg(next_rx_text_font_.pointSize()));
|
||||
|
||||
if (next_compose_text_font_.fromString (settings_->value ("composeTextFont", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_compose_text_font_ != compose_text_font_)
|
||||
{
|
||||
compose_text_font_ = next_compose_text_font_;
|
||||
Q_EMIT self_->compose_text_font_changed (compose_text_font_);
|
||||
}
|
||||
else
|
||||
{
|
||||
next_compose_text_font_ = compose_text_font_;
|
||||
}
|
||||
ui_->composeFontButton->setText(QString("Font (%1 %2)").arg(next_compose_text_font_.family()).arg(next_compose_text_font_.pointSize()));
|
||||
|
||||
if (next_table_font_.fromString (settings_->value ("tableFont", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_table_font_ != table_font_)
|
||||
{
|
||||
table_font_ = next_table_font_;
|
||||
Q_EMIT self_->table_font_changed (table_font_);
|
||||
}
|
||||
else
|
||||
{
|
||||
next_table_font_ = table_font_;
|
||||
}
|
||||
ui_->tableFontButton->setText(QString("Font (%1 %2)").arg(next_table_font_.family()).arg(next_table_font_.pointSize()));
|
||||
|
||||
id_interval_ = settings_->value ("IDint", 0).toInt ();
|
||||
ntrials_ = settings_->value ("nTrials", 6).toInt ();
|
||||
txDelay_ = settings_->value ("TxDelay",0.2).toDouble();
|
||||
@@ -1395,6 +1525,8 @@ void Configuration::impl::read_settings ()
|
||||
RxBandwidth_ = settings_->value ("RxBandwidth", 2500).toInt ();
|
||||
save_directory_ = settings_->value ("SaveDir", default_save_directory_.absolutePath ()).toString ();
|
||||
azel_directory_ = settings_->value ("AzElDir", default_azel_directory_.absolutePath ()).toString ();
|
||||
sound_dm_path_ = settings_->value ("SoundDMPath", "").toString ();
|
||||
sound_am_path_ = settings_->value ("SoundAMPath", "").toString ();
|
||||
|
||||
{
|
||||
//
|
||||
@@ -1456,11 +1588,13 @@ void Configuration::impl::read_settings ()
|
||||
|
||||
transmit_directed_ = settings_->value ("TransmitDirected", true).toBool();
|
||||
autoreply_off_at_startup_ = settings_->value ("AutoreplyOFF", false).toBool ();
|
||||
beacon_anywhere_ = settings_->value("BeaconAnywhere", false).toBool();
|
||||
relay_disabled_ = settings_->value ("RelayOFF", 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 ();
|
||||
id_after_73_ = settings_->value ("After73", false).toBool ();
|
||||
tx_QSY_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
|
||||
tx_qsy_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
|
||||
use_dynamic_info_ = settings_->value ("AutoGrid", false).toBool ();
|
||||
|
||||
auto loadedMacros = settings_->value ("Macros", QStringList {"TNX 73 GL"}).toStringList();
|
||||
@@ -1517,6 +1651,9 @@ void Configuration::impl::read_settings ()
|
||||
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
|
||||
beacon_ = settings_->value ("TxBeacon", 30).toInt ();
|
||||
watchdog_ = settings_->value ("TxWatchdog", 0).toInt ();
|
||||
if(watchdog_){
|
||||
watchdog_ = qMax(5, watchdog_);
|
||||
}
|
||||
TX_messages_ = settings_->value ("Tx2QSO", true).toBool ();
|
||||
enable_VHF_features_ = settings_->value("VHFUHF",false).toBool ();
|
||||
decode_at_52s_ = settings_->value("Decode52",false).toBool ();
|
||||
@@ -1529,6 +1666,9 @@ void Configuration::impl::read_settings ()
|
||||
rig_params_.poll_interval = settings_->value ("Polling", 0).toInt ();
|
||||
rig_params_.split_mode = settings_->value ("SplitMode", QVariant::fromValue (TransceiverFactory::split_mode_none)).value<TransceiverFactory::SplitMode> ();
|
||||
opCall_ = settings_->value ("OpCall", "").toString ();
|
||||
aprs_server_name_ = settings_->value ("aprsServer", "rotate.aprs2.net").toString ();
|
||||
aprs_server_port_ = settings_->value ("aprsServerPort", 14580).toUInt ();
|
||||
aprs_passcode_ = settings_->value ("aprsPasscode", "").toString();
|
||||
udp_server_name_ = settings_->value ("UDPServer", "127.0.0.1").toString ();
|
||||
udp_server_port_ = settings_->value ("UDPServerPort", 2237).toUInt ();
|
||||
n1mm_server_name_ = settings_->value ("N1MMServer", "127.0.0.1").toString ();
|
||||
@@ -1552,18 +1692,32 @@ void Configuration::impl::write_settings ()
|
||||
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 ("CQMessage", cq_);
|
||||
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("colorCQ",color_cq_);
|
||||
settings_->setValue("colorMyCall",color_mycall_);
|
||||
settings_->setValue("color_rx_background",color_rx_background_);
|
||||
settings_->setValue("color_rx_foreground",color_rx_foreground_);
|
||||
settings_->setValue("color_compose_background",color_compose_background_);
|
||||
settings_->setValue("color_compose_foreground",color_compose_foreground_);
|
||||
settings_->setValue("color_tx_foreground",color_tx_foreground_);
|
||||
settings_->setValue("colorDXCC",color_DXCC_);
|
||||
settings_->setValue("colorNewCall",color_NewCall_);
|
||||
|
||||
settings_->setValue("colorTableBackground",color_table_background_);
|
||||
settings_->setValue("colorTableHighlight",color_table_highlight_);
|
||||
settings_->setValue("colorTableForeground",color_table_foreground_);
|
||||
|
||||
|
||||
settings_->setValue ("Font", font_.toString ());
|
||||
settings_->setValue ("DecodedTextFont", decoded_text_font_.toString ());
|
||||
settings_->setValue ("RXTextFont", rx_text_font_.toString ());
|
||||
settings_->setValue ("TXTextFont", tx_text_font_.toString ());
|
||||
settings_->setValue ("composeTextFont", compose_text_font_.toString ());
|
||||
settings_->setValue ("tableFont", table_font_.toString());
|
||||
|
||||
settings_->setValue ("IDint", id_interval_);
|
||||
settings_->setValue ("nTrials", ntrials_);
|
||||
settings_->setValue ("TxDelay", txDelay_);
|
||||
@@ -1573,6 +1727,8 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("PTTport", rig_params_.ptt_port);
|
||||
settings_->setValue ("SaveDir", save_directory_.absolutePath ());
|
||||
settings_->setValue ("AzElDir", azel_directory_.absolutePath ());
|
||||
settings_->setValue ("SoundDMPath", sound_dm_path_);
|
||||
settings_->setValue ("SoundAMPath", sound_am_path_);
|
||||
|
||||
if (default_audio_input_device_selected_)
|
||||
{
|
||||
@@ -1597,11 +1753,13 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
|
||||
settings_->setValue ("TransmitDirected", transmit_directed_);
|
||||
settings_->setValue ("AutoreplyOFF", autoreply_off_at_startup_);
|
||||
settings_->setValue ("BeaconAnywhere", beacon_anywhere_);
|
||||
settings_->setValue ("RelayOFF", relay_disabled_);
|
||||
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
|
||||
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
|
||||
settings_->setValue ("PSKReporter", spot_to_reporting_networks_);
|
||||
settings_->setValue ("After73", id_after_73_);
|
||||
settings_->setValue ("TxQSYAllowed", tx_QSY_allowed_);
|
||||
settings_->setValue ("TxQSYAllowed", tx_qsy_allowed_);
|
||||
settings_->setValue ("Macros", macros_.stringList ());
|
||||
settings_->setValue (versionedFrequenciesSettingsKey, QVariant::fromValue (frequencies_.frequency_list ()));
|
||||
settings_->setValue ("stations", QVariant::fromValue (stations_.station_list ()));
|
||||
@@ -1643,6 +1801,9 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("x2ToneSpacing", x2ToneSpacing_);
|
||||
settings_->setValue ("x4ToneSpacing", x4ToneSpacing_);
|
||||
settings_->setValue ("OpCall", opCall_);
|
||||
settings_->setValue ("aprsServer", aprs_server_name_);
|
||||
settings_->setValue ("aprsServerPort", aprs_server_port_);
|
||||
settings_->setValue ("aprsPasscode", aprs_passcode_);
|
||||
settings_->setValue ("UDPServer", udp_server_name_);
|
||||
settings_->setValue ("UDPServerPort", udp_server_port_);
|
||||
settings_->setValue ("N1MMServer", n1mm_server_name_);
|
||||
@@ -1916,20 +2077,45 @@ void Configuration::impl::accept ()
|
||||
if (next_font_ != font_)
|
||||
{
|
||||
font_ = next_font_;
|
||||
Q_EMIT self_->text_font_changed (font_);
|
||||
Q_EMIT self_->gui_text_font_changed (font_);
|
||||
}
|
||||
|
||||
if (next_decoded_text_font_ != decoded_text_font_)
|
||||
if (next_tx_text_font_ != tx_text_font_)
|
||||
{
|
||||
decoded_text_font_ = next_decoded_text_font_;
|
||||
Q_EMIT self_->decoded_text_font_changed (decoded_text_font_);
|
||||
tx_text_font_ = next_tx_text_font_;
|
||||
Q_EMIT self_->tx_text_font_changed (tx_text_font_);
|
||||
}
|
||||
|
||||
color_CQ_ = next_color_CQ_;
|
||||
color_MyCall_ = next_color_MyCall_;
|
||||
color_ReceivedMsg_ = next_color_ReceivedMsg_;
|
||||
if (next_rx_text_font_ != rx_text_font_)
|
||||
{
|
||||
rx_text_font_ = next_rx_text_font_;
|
||||
Q_EMIT self_->rx_text_font_changed (rx_text_font_);
|
||||
}
|
||||
|
||||
if (next_compose_text_font_ != compose_text_font_)
|
||||
{
|
||||
compose_text_font_ = next_compose_text_font_;
|
||||
Q_EMIT self_->compose_text_font_changed (compose_text_font_);
|
||||
}
|
||||
|
||||
if (next_table_font_ != table_font_)
|
||||
{
|
||||
table_font_ = next_table_font_;
|
||||
Q_EMIT self_->table_font_changed (table_font_);
|
||||
}
|
||||
|
||||
color_cq_ = next_color_cq_;
|
||||
color_mycall_ = next_color_mycall_;
|
||||
color_rx_background_ = next_color_rx_background_;
|
||||
color_rx_foreground_ = next_color_rx_foreground_;
|
||||
color_compose_background_ = next_color_compose_background_;
|
||||
color_compose_foreground_ = next_color_compose_foreground_;
|
||||
color_tx_foreground_ = next_color_tx_foreground_;
|
||||
color_DXCC_ = next_color_DXCC_;
|
||||
color_NewCall_ = next_color_NewCall_;
|
||||
color_table_background_ = next_color_table_background_;
|
||||
color_table_highlight_ = next_color_table_highlight_;
|
||||
color_table_foreground_ = next_color_table_foreground_;
|
||||
|
||||
Q_EMIT self_->colors_changed();
|
||||
|
||||
@@ -2015,8 +2201,8 @@ void Configuration::impl::accept ()
|
||||
my_callsign_ = ui_->callsign_line_edit->text ();
|
||||
my_grid_ = ui_->grid_line_edit->text ();
|
||||
my_station_ = ui_->station_message_line_edit->text().toUpper();
|
||||
cq_ = ui_->cq_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();
|
||||
@@ -2028,28 +2214,28 @@ void Configuration::impl::accept ()
|
||||
degrade_ = ui_->sbDegrade->value ();
|
||||
RxBandwidth_ = ui_->sbBandwidth->value ();
|
||||
id_after_73_ = ui_->CW_id_after_73_check_box->isChecked ();
|
||||
tx_QSY_allowed_ = ui_->tx_QSY_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 ();
|
||||
beacon_anywhere_ = ui_->beacon_anywhere_check_box->isChecked();
|
||||
relay_disabled_ = ui_->relay_disabled_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 ();
|
||||
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 ();
|
||||
DXCC_ = ui_->DXCC_check_box->isChecked ();
|
||||
ppfx_ = ui_->ppfx_check_box->isChecked ();
|
||||
clear_DX_ = ui_->clear_DX_check_box->isChecked ();
|
||||
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 ());
|
||||
save_directory_ = ui_->save_path_display_label->text ();
|
||||
azel_directory_ = ui_->azel_path_display_label->text ();
|
||||
sound_dm_path_ = ui_->sound_dm_path_display_label->text();
|
||||
sound_am_path_ = ui_->sound_am_path_display_label->text();
|
||||
enable_VHF_features_ = ui_->enable_VHF_features_check_box->isChecked ();
|
||||
decode_at_52s_ = ui_->decode_at_52s_check_box->isChecked ();
|
||||
single_decode_ = ui_->single_decode_check_box->isChecked ();
|
||||
@@ -2064,6 +2250,10 @@ void Configuration::impl::accept ()
|
||||
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
|
||||
opCall_=ui_->opCallEntry->text();
|
||||
|
||||
aprs_server_name_ = ui_->aprs_server_line_edit->text();
|
||||
aprs_server_port_ = ui_->aprs_server_port_spin_box->value();
|
||||
aprs_passcode_ = ui_->aprs_passcode_line_edit->text();
|
||||
|
||||
auto newUdpEnabled = ui_->udpEnable->isChecked();
|
||||
auto new_server = ui_->udp_server_line_edit->text ();
|
||||
if (new_server != udp_server_name_ || newUdpEnabled != udpEnabled_)
|
||||
@@ -2149,66 +2339,178 @@ void Configuration::impl::reject ()
|
||||
void Configuration::impl::on_font_push_button_clicked ()
|
||||
{
|
||||
next_font_ = QFontDialog::getFont (0, next_font_, this);
|
||||
|
||||
ui_->font_push_button->setText(QString("Application Font (%1 %2)").arg(next_font_.family()).arg(next_font_.pointSize()));
|
||||
}
|
||||
|
||||
void Configuration::impl::on_tableFontButton_clicked ()
|
||||
{
|
||||
next_table_font_ = QFontDialog::getFont (0, next_table_font_, this);
|
||||
ui_->tableFontButton->setText(QString("Table Font (%1 %2)").arg(next_table_font_.family()).arg(next_table_font_.pointSize()));
|
||||
}
|
||||
|
||||
|
||||
QColor getColor(QColor initial, QWidget *parent, QString title){
|
||||
QList<QColor> custom = {
|
||||
QColor("#66FF66"),
|
||||
QColor("#FF6666"),
|
||||
QColor("#FFEAA7"),
|
||||
QColor("#3498DB")
|
||||
};
|
||||
|
||||
auto d = new QColorDialog(initial, parent);
|
||||
d->setWindowTitle(title);
|
||||
for(int i = 0; i < custom.length(); i++){
|
||||
d->setCustomColor(i, custom.at(i));
|
||||
}
|
||||
|
||||
if(d->exec() == QColorDialog::Accepted){
|
||||
return d->selectedColor();
|
||||
} else {
|
||||
return initial;
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbCQmsg_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_CQ_, this, "CQ and BEACON Messages Color");
|
||||
auto new_color = getColor(next_color_cq_, this, "CQ Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_CQ_ = new_color;
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1").arg(next_color_CQ_.name()));
|
||||
next_color_cq_ = new_color;
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1; color: %2").arg(next_color_cq_.name()).arg(next_color_table_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbMyCall_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_MyCall_, this, "Directed Messages Color");
|
||||
auto new_color = getColor(next_color_mycall_, this, "Directed Messages Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_MyCall_ = new_color;
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(next_color_MyCall_.name()));
|
||||
next_color_mycall_ = new_color;
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1; color: %2").arg(next_color_mycall_.name()).arg(next_color_table_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbTxMsg_clicked()
|
||||
void Configuration::impl::on_tableBackgroundButton_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_ReceivedMsg_, this, "Received Messages Textarea Color");
|
||||
auto new_color = getColor(next_color_table_background_, this, "Table Background Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_ReceivedMsg_ = new_color;
|
||||
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_ReceivedMsg_.name()));
|
||||
next_color_table_background_ = new_color;
|
||||
ui_->tableBackgroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_table_background_.name()).arg(next_color_table_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewDXCC_clicked()
|
||||
void Configuration::impl::on_tableSelectedRowBackgroundButton_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_DXCC_, this, "New DXCC Messages Color");
|
||||
auto new_color = getColor(next_color_table_highlight_, this, "Table Selected Row Background Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_DXCC_ = new_color;
|
||||
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(next_color_DXCC_.name()));
|
||||
next_color_table_highlight_ = new_color;
|
||||
ui_->tableSelectionBackgroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_table_highlight_.name()).arg(next_color_table_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_pbNewCall_clicked()
|
||||
void Configuration::impl::on_tableForegroundButton_clicked()
|
||||
{
|
||||
auto new_color = QColorDialog::getColor(next_color_NewCall_, this, "New Call Messages Color");
|
||||
auto new_color = getColor(next_color_table_foreground_, this, "Table Foreground Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_NewCall_ = new_color;
|
||||
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(next_color_NewCall_.name()));
|
||||
next_color_table_foreground_ = new_color;
|
||||
ui_->tableBackgroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_table_background_.name()).arg(next_color_table_foreground_.name()));
|
||||
ui_->tableSelectionBackgroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_table_highlight_.name()).arg(next_color_table_foreground_.name()));
|
||||
ui_->labCQ->setStyleSheet(QString("background: %1; color: %2").arg(next_color_cq_.name()).arg(next_color_table_foreground_.name()));
|
||||
ui_->labMyCall->setStyleSheet(QString("background: %1; color: %2").arg(next_color_mycall_.name()).arg(next_color_table_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_decoded_text_font_push_button_clicked ()
|
||||
void Configuration::impl::on_rxBackgroundButton_clicked()
|
||||
{
|
||||
next_decoded_text_font_ = QFontDialog::getFont (0, decoded_text_font_ , this
|
||||
auto new_color = getColor(next_color_rx_background_, this, "Received Messages Background Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_rx_background_ = new_color;
|
||||
ui_->rxLabel->setStyleSheet(QString("background: %1; color: %2").arg(color_rx_background_.name()).arg(color_rx_foreground_.name()));
|
||||
ui_->rxForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_rx_background_.name()).arg(next_color_rx_foreground_.name()));
|
||||
ui_->txForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_rx_background_.name()).arg(next_color_tx_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_rxForegroundButton_clicked()
|
||||
{
|
||||
auto new_color = getColor(next_color_rx_foreground_, this, "Received Messages Foreground Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_rx_foreground_ = new_color;
|
||||
ui_->rxLabel->setStyleSheet(QString("background: %1; color: %2").arg(color_rx_background_.name()).arg(color_rx_foreground_.name()));
|
||||
ui_->rxForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_rx_background_.name()).arg(next_color_rx_foreground_.name()));
|
||||
ui_->txForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_rx_background_.name()).arg(next_color_tx_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_rxFontButton_clicked ()
|
||||
{
|
||||
next_rx_text_font_ = QFontDialog::getFont (0, next_rx_text_font_ , this
|
||||
, tr ("Font Chooser")
|
||||
#if QT_VERSION >= 0x050201
|
||||
, QFontDialog::MonospacedFonts
|
||||
, 0
|
||||
#endif
|
||||
);
|
||||
ui_->rxFontButton->setText(QString("Font (%1 %2)").arg(next_rx_text_font_.family()).arg(next_rx_text_font_.pointSize()));
|
||||
}
|
||||
|
||||
void Configuration::impl::on_composeBackgroundButton_clicked()
|
||||
{
|
||||
auto new_color = getColor(next_color_compose_background_, this, "Compose Messages Background Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_compose_background_ = new_color;
|
||||
ui_->composeLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_compose_background_.name()).arg(next_color_compose_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_composeForegroundButton_clicked()
|
||||
{
|
||||
auto new_color = getColor(next_color_compose_foreground_, this, "Compose Messages Foreground Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_compose_foreground_ = new_color;
|
||||
ui_->composeLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_compose_background_.name()).arg(next_color_compose_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_txForegroundButton_clicked()
|
||||
{
|
||||
auto new_color = getColor(next_color_tx_foreground_, this, "Transmitted Messages Foreground Color");
|
||||
if (new_color.isValid ())
|
||||
{
|
||||
next_color_tx_foreground_ = new_color;
|
||||
ui_->rxForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_rx_background_.name()).arg(next_color_rx_foreground_.name()));
|
||||
ui_->txForegroundLabel->setStyleSheet(QString("background: %1; color: %2").arg(next_color_rx_background_.name()).arg(next_color_tx_foreground_.name()));
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_txFontButton_clicked ()
|
||||
{
|
||||
next_tx_text_font_ = QFontDialog::getFont (0, next_tx_text_font_ , this
|
||||
, tr ("Font Chooser")
|
||||
#if QT_VERSION >= 0x050201
|
||||
, 0
|
||||
#endif
|
||||
);
|
||||
|
||||
ui_->txFontButton->setText(QString("Font (%1 %2)").arg(next_tx_text_font_.family()).arg(next_tx_text_font_.pointSize()));
|
||||
}
|
||||
|
||||
void Configuration::impl::on_composeFontButton_clicked ()
|
||||
{
|
||||
next_compose_text_font_ = QFontDialog::getFont (0, next_compose_text_font_ , this
|
||||
, tr ("Font Chooser")
|
||||
#if QT_VERSION >= 0x050201
|
||||
, 0
|
||||
#endif
|
||||
);
|
||||
ui_->composeFontButton->setText(QString("Font (%1 %2)").arg(next_compose_text_font_.family()).arg(next_compose_text_font_.pointSize()));
|
||||
}
|
||||
|
||||
void Configuration::impl::on_PTT_port_combo_box_activated (int /* index */)
|
||||
@@ -2328,6 +2630,14 @@ void Configuration::impl::on_qth_message_line_edit_textChanged(QString const &te
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_cq_message_line_edit_textChanged(QString const &text)
|
||||
{
|
||||
QString upper = text.toUpper();
|
||||
if(text != upper){
|
||||
ui_->cq_message_line_edit->setText (upper);
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_reply_message_line_edit_textChanged(QString const &text)
|
||||
{
|
||||
QString upper = text.toUpper();
|
||||
@@ -2574,6 +2884,68 @@ void Configuration::impl::on_azel_path_select_push_button_clicked (bool /* check
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_dm_path_select_push_button_clicked(){
|
||||
QStringList filters;
|
||||
filters << "Audio files (*.wav)"
|
||||
<< "Any files (*)";
|
||||
|
||||
QFileDialog fd {this, tr ("Sound File"), ui_->sound_dm_path_display_label->text ()};
|
||||
fd.setNameFilters(filters);
|
||||
|
||||
if (fd.exec ()) {
|
||||
if (fd.selectedFiles ().size ()) {
|
||||
if(rig_params_.ptt_type == TransceiverFactory::PTT_method_VOX){
|
||||
QMessageBox::warning(this, "Notifications Sounds Warning", "You have enabled notification sounds while using VOX. To avoid transmitting these notification sounds, please make sure your rig is using a different sound card than your system.");
|
||||
}
|
||||
ui_->sound_dm_path_display_label->setText(fd.selectedFiles().at(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_dm_path_test_push_button_clicked(){
|
||||
auto path = ui_->sound_dm_path_display_label->text();
|
||||
if(path.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
QSound::play(path);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_dm_path_reset_push_button_clicked(){
|
||||
ui_->sound_dm_path_display_label->clear();
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_am_path_select_push_button_clicked(){
|
||||
QStringList filters;
|
||||
filters << "Audio files (*.wav)"
|
||||
<< "Any files (*)";
|
||||
|
||||
QFileDialog fd {this, tr ("Sound File"), ui_->sound_am_path_display_label->text ()};
|
||||
fd.setNameFilters(filters);
|
||||
|
||||
if (fd.exec ()) {
|
||||
if (fd.selectedFiles ().size ()) {
|
||||
if(rig_params_.ptt_type == TransceiverFactory::PTT_method_VOX){
|
||||
QMessageBox::warning(this, "Notifications Sounds Warning", "You have enabled notification sounds while using VOX. To avoid transmitting these notification sounds, please make sure your rig is using a different sound card than your system.");
|
||||
}
|
||||
ui_->sound_am_path_display_label->setText(fd.selectedFiles().at(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_am_path_test_push_button_clicked(){
|
||||
auto path = ui_->sound_am_path_display_label->text();
|
||||
if(path.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
QSound::play(path);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_sound_am_path_reset_push_button_clicked(){
|
||||
ui_->sound_am_path_display_label->clear();
|
||||
}
|
||||
|
||||
void Configuration::impl::on_calibration_intercept_spin_box_valueChanged (double)
|
||||
{
|
||||
rig_active_ = false; // force reset
|
||||
|
||||
@@ -98,13 +98,16 @@ public:
|
||||
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;
|
||||
QString cq_message () const;
|
||||
QString reply_message () const;
|
||||
QFont table_font() const;
|
||||
QFont text_font () const;
|
||||
QFont decoded_text_font () const;
|
||||
QFont rx_text_font () const;
|
||||
QFont tx_text_font () const;
|
||||
QFont compose_text_font () const;
|
||||
qint32 id_interval () const;
|
||||
qint32 ntrials() const;
|
||||
qint32 aggressive() const;
|
||||
@@ -112,11 +115,13 @@ public:
|
||||
double degrade() const;
|
||||
double txDelay() const;
|
||||
bool id_after_73 () const;
|
||||
bool tx_QSY_allowed () 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 beacon_anywhere() const;
|
||||
bool relay_off() const;
|
||||
bool monitor_off_at_startup () const;
|
||||
bool monitor_last_used () const;
|
||||
bool log_as_DATA () const;
|
||||
@@ -149,6 +154,9 @@ public:
|
||||
bool EMEonly() const;
|
||||
bool post_decodes () const;
|
||||
QString opCall() const;
|
||||
QString aprs_server_name () const;
|
||||
port_type aprs_server_port () const;
|
||||
QString aprs_passcode () const;
|
||||
QString udp_server_name () const;
|
||||
port_type udp_server_port () const;
|
||||
QString n1mm_server_name () const;
|
||||
@@ -171,11 +179,20 @@ public:
|
||||
QStringListModel const * macros () const;
|
||||
QDir save_directory () const;
|
||||
QDir azel_directory () const;
|
||||
QString sound_dm_path() const;
|
||||
QString sound_am_path() const;
|
||||
QString rig_name () const;
|
||||
Type2MsgGen type_2_msg_gen () const;
|
||||
QColor color_table_background() const;
|
||||
QColor color_table_highlight() const;
|
||||
QColor color_table_foreground() const;
|
||||
QColor color_CQ () const;
|
||||
QColor color_MyCall () const;
|
||||
QColor color_ReceivedMsg () const;
|
||||
QColor color_rx_background () const;
|
||||
QColor color_rx_foreground () const;
|
||||
QColor color_tx_foreground () const;
|
||||
QColor color_compose_background () const;
|
||||
QColor color_compose_foreground () const;
|
||||
QColor color_DXCC () const;
|
||||
QColor color_NewCall () const;
|
||||
bool pwrBandTxMemory () const;
|
||||
@@ -268,8 +285,11 @@ public:
|
||||
// These signals indicate a font has been selected and accepted for
|
||||
// the application text and decoded text respectively.
|
||||
//
|
||||
Q_SIGNAL void text_font_changed (QFont);
|
||||
Q_SIGNAL void decoded_text_font_changed (QFont);
|
||||
Q_SIGNAL void gui_text_font_changed (QFont);
|
||||
Q_SIGNAL void tx_text_font_changed (QFont);
|
||||
Q_SIGNAL void rx_text_font_changed (QFont);
|
||||
Q_SIGNAL void compose_text_font_changed (QFont);
|
||||
Q_SIGNAL void table_font_changed (QFont);
|
||||
Q_SIGNAL void colors_changed ();
|
||||
|
||||
//
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <QThread>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
#include "NetworkServerLookup.hpp"
|
||||
|
||||
#include "moc_DXLabSuiteCommanderTransceiver.cpp"
|
||||
@@ -151,10 +153,10 @@ void DXLabSuiteCommanderTransceiver::do_ptt (bool on)
|
||||
simple_command (on ? "<command:5>CmdTX<parameters:0>" : "<command:5>CmdRX<parameters:0>");
|
||||
|
||||
bool tx {!on};
|
||||
auto start = QDateTime::currentMSecsSinceEpoch ();
|
||||
auto start = DriftingDateTime::currentMSecsSinceEpoch ();
|
||||
// we must now wait for Tx on the rig, we will wait a short while
|
||||
// before bailing out
|
||||
while (tx != on && QDateTime::currentMSecsSinceEpoch () - start < 1000)
|
||||
while (tx != on && DriftingDateTime::currentMSecsSinceEpoch () - start < 1000)
|
||||
{
|
||||
auto reply = command_with_reply ("<command:9>CmdSendTx<parameters:0>");
|
||||
if (0 == reply.indexOf ("<CmdTX:"))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
WSJTX_BUNDLE="`echo "$0" | sed -e 's/\/Contents\/MacOS\/.*//'`"
|
||||
WSJTX_RESOURCES="$WSJTX_BUNDLE/Contents/Resources"
|
||||
WSJTX_TEMP="/tmp/wsjtx/$UID"
|
||||
WSJTX_TEMP="/tmp/js8call/$UID"
|
||||
|
||||
echo "running $0"
|
||||
echo "WSJTX_BUNDLE: $WSJTX_BUNDLE"
|
||||
@@ -13,4 +13,4 @@ export "DYLD_LIBRARY_PATH=$WSJTX_RESOURCES/lib"
|
||||
export "PATH=$WSJTX_RESOURCES/bin:$PATH"
|
||||
|
||||
#export
|
||||
exec "$WSJTX_RESOURCES/bin/wsjtx"
|
||||
exec "$WSJTX_RESOURCES/bin/js8call"
|
||||
@@ -1,3 +1,7 @@
|
||||
|
||||
Notes on JS8Call Installation for Mac OS X
|
||||
(replace all instances of WSJT-X with JS8Call)
|
||||
|
||||
Notes on WSJT-X Installation for Mac OS X
|
||||
-----------------------------------------
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <QDebug>
|
||||
#include "commons.h"
|
||||
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
#include "moc_Detector.cpp"
|
||||
|
||||
extern "C" {
|
||||
@@ -42,7 +44,7 @@ bool Detector::reset ()
|
||||
void Detector::clear ()
|
||||
{
|
||||
// set index to roughly where we are in time (1ms resolution)
|
||||
// qint64 now (QDateTime::currentMSecsSinceEpoch ());
|
||||
// qint64 now (DriftingDateTime::currentMSecsSinceEpoch ());
|
||||
// unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000));
|
||||
// dec_data.params.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (dec_data.d2) / sizeof (dec_data.d2[0])));
|
||||
dec_data.params.kin = 0;
|
||||
@@ -125,7 +127,7 @@ unsigned Detector::secondInPeriod () const
|
||||
{
|
||||
// we take the time of the data as the following assuming no latency
|
||||
// delivering it to us (not true but close enough for us)
|
||||
qint64 now (QDateTime::currentMSecsSinceEpoch ());
|
||||
qint64 now (DriftingDateTime::currentMSecsSinceEpoch ());
|
||||
|
||||
unsigned secondInToday ((now % 86400000LL) / 1000);
|
||||
return secondInToday % m_period;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
qint64 driftms = 0;
|
||||
|
||||
QDateTime DriftingDateTime::currentDateTime(){
|
||||
return QDateTime::currentDateTime().addMSecs(driftms);
|
||||
}
|
||||
|
||||
QDateTime DriftingDateTime::currentDateTimeUtc(){
|
||||
return QDateTime::currentDateTimeUtc().addMSecs(driftms);
|
||||
}
|
||||
|
||||
qint64 DriftingDateTime::currentMSecsSinceEpoch(){
|
||||
return QDateTime::currentMSecsSinceEpoch() + driftms;
|
||||
}
|
||||
|
||||
qint64 DriftingDateTime::drift(){
|
||||
return driftms;
|
||||
}
|
||||
|
||||
void DriftingDateTime::setDrift(qint64 ms){
|
||||
driftms = ms;
|
||||
}
|
||||
|
||||
qint64 DriftingDateTime::incrementDrift(qint64 msdelta){
|
||||
driftms += msdelta;
|
||||
return driftms;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef DRIFTINGDATETIME_H
|
||||
#define DRIFTINGDATETIME_H
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
class DriftingDateTime /*: QDateTime*/
|
||||
{
|
||||
public:
|
||||
static QDateTime currentDateTime();
|
||||
static QDateTime currentDateTimeUtc();
|
||||
static qint64 currentMSecsSinceEpoch();
|
||||
|
||||
static qint64 drift();
|
||||
static void setDrift(qint64 ms);
|
||||
static qint64 incrementDrift(qint64 msdelta);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif // DRIFTINGDATETIME_H
|
||||
@@ -26,16 +26,16 @@ 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
|
||||
{ 1842000, Modes::JS8, IARURegions::ALL}, // 2 above
|
||||
{ 3578000, Modes::JS8, IARURegions::ALL}, // 5 above
|
||||
{ 7078000, Modes::JS8, IARURegions::ALL}, // 4 above
|
||||
{10130000, Modes::JS8, IARURegions::ALL}, // 6 below
|
||||
{14078000, Modes::JS8, IARURegions::ALL}, // 4 above
|
||||
{18104000, Modes::JS8, IARURegions::ALL}, // 4 above
|
||||
{21078000, Modes::JS8, IARURegions::ALL}, // 4 above
|
||||
{24922000, Modes::JS8, IARURegions::ALL}, // 9 above
|
||||
{28078000, Modes::JS8, IARURegions::ALL}, // 4 above
|
||||
{50318000, Modes::JS8, IARURegions::ALL}, // 5 above
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
JT4 JT9 9+65 JT65 QRA SCAT M144 WSPR Echo
|
||||
---------------------------------------------------------------------
|
||||
0. txFirstCheckBox 11 111 1 11 11 11 1
|
||||
1. TxFreqSpinBox 11 111 1 11 11
|
||||
2. RxFreqSpinBox 11 111 1 11 11 1
|
||||
3. sbFtol 1 11 1 11 11 1
|
||||
4. rptSpinBox 11 111 1 11 11 11 1
|
||||
5. sbTR 11 1
|
||||
6. sbCQRxFreq 1
|
||||
7. cbShMsgs 1 1
|
||||
8. cbFast9 11
|
||||
9. cbAutoSeq 1
|
||||
10. cbTx6 1
|
||||
11. pbTxMode 1
|
||||
12. pbR2T 11 11 1 11 11
|
||||
13. pbT2R 11 11 1 11 11
|
||||
14. cbTxLock 1 11 1 11 11
|
||||
15. sbSubMode 1 1 1 11 11
|
||||
16. syncSpinBox 1 1 1 11 11
|
||||
17. WSPR_Controls_Widget 1
|
||||
18. ClrAvgButton 11 1
|
||||
---------------------------------------------------------------------
|
||||
19. FastNormalDeep 11 11 1 11 1 1
|
||||
20. IncludeAveraging 1 1
|
||||
21. IncludeCorrelation 1 1
|
||||
22. EchoGraph 1
|
||||
---------------------------------------------------------------------
|
||||
|
||||
For each mode:
|
||||
Column 1 applies when VHF features is OFF (or col 2 absent)
|
||||
Column 2 (if present) applies when VHF features is ON
|
||||
Column 3 (JT9 only) applies for submodes E-H with Fast checked
|
||||
@@ -1,416 +1 @@
|
||||
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Installing WSJT-X
|
||||
=================
|
||||
|
||||
Binary packages of WSJT-X are available from the project web site:
|
||||
|
||||
http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
|
||||
|
||||
Building from Source
|
||||
====================
|
||||
|
||||
On Linux systems some of the prerequisite libraries are available in
|
||||
the mainstream distribution repositories. They are Qt v5 and FFTW v3.
|
||||
For MS Windows see the section "Building from Source on MS Windows"
|
||||
below. For Apple Mac see the section "Building from Source on Apple
|
||||
Mac".
|
||||
|
||||
Qt v5, preferably v5.1 or later is required to build WSJT-X.
|
||||
|
||||
Qt v5 multimedia support and serial port is necessary as well as the
|
||||
core Qt v5 components, normally installing the Qt multimedia
|
||||
development package and Qt serialport development package are
|
||||
sufficient to pull in all the required Qt components and dependants as
|
||||
a single transaction. On some systems the Qt multimedia plugin
|
||||
component is separate in the distribution repository an it may also
|
||||
need installing.
|
||||
|
||||
The single precision FFTW v3 library libfftw3f is required along with
|
||||
the libfftw library development package. Normally installing the
|
||||
library development package pulls in all the FFTW v3 libraries
|
||||
including the single precision variant.
|
||||
|
||||
The Hamlib library optionally requires the libusb-1.0 library, if the
|
||||
development version (libusb-1.0-dev) is available Hamlib will
|
||||
configure its custom USB device back end drivers. Most rigs do not
|
||||
require this so normally you can choose not to install libusb-1.0-dev
|
||||
but if you have a SoftRock USB or similar SDR that uses a custom USB
|
||||
interface then it is required.
|
||||
|
||||
The Hamlib library is required. Currently WSJT-X needs to be built
|
||||
using a forked version of the Hamlib git master. This fork contains
|
||||
patches not yet accepted by the Hamlib development team which are
|
||||
essential for correct operation of WSJT-X. To build the Hamlib fork
|
||||
from sources something like the following recipe should suffice:
|
||||
|
||||
$ mkdir ~/hamlib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
$ mkdir ../build
|
||||
$ cd ../build
|
||||
$ ../src/configure --prefix=$HOME/hamlib-prefix \
|
||||
--disable-shared --enable-static \
|
||||
--without-cxx-binding --disable-winradio \
|
||||
CFLAGS="-g -O2 -fdata-sections -ffunction-sections" \
|
||||
LDFLAGS="-Wl,--gc-sections"
|
||||
$ make
|
||||
$ make install-strip
|
||||
|
||||
This will build a binary hamlib package located at ~/hamlib-prefix so
|
||||
you will need to add that to your CMAKE_PREFIX_PATH variable in your
|
||||
WSJT-X build. On Linux that is probably the only path you have on
|
||||
CMAKE_PREFIX_PATH unless you are using a locally installed Qt
|
||||
installation.
|
||||
|
||||
To get the sources either download and extract a source tarball from
|
||||
the project web site or preferably fetch the sources directly from the
|
||||
project's subversion repository. The project svn repository has a
|
||||
non-standard layout in that the WSJT-X project is not on the trunk,
|
||||
instead the main code line is in a branch at ^/branches/wsjtx
|
||||
|
||||
$ mkdir -p ~/wsjtx-prefix/build
|
||||
$ cd ~/wsjtx-prefix
|
||||
$ svn checkout svn://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx src
|
||||
|
||||
To build WSJT-X you will need CMake and asciidoc installed.
|
||||
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ cmake -D CMAKE_PREFIX_PATH=~/hamlib-prefix ../src
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
The recipe above will install into /usr by default, if you wish to
|
||||
install in you own directory you can add a prefix-path to the
|
||||
configure step like:
|
||||
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ cmake -D CMAKE_PREFIX_PATH=~/hamlib-prefix \
|
||||
-D CMAKE_INSTALL_PREFIX=~/wsjtx-prefix ../src
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
this will install WSJT-X at ~/wsjtx-prefix.
|
||||
|
||||
|
||||
Building from Source on MS Windows
|
||||
==================================
|
||||
|
||||
Because building on MS Windows is quite complicated there is an
|
||||
Software Development Kit available that provides all the prerequisite
|
||||
libraries and tools for building WSJT-X. This SDK is called JT-SDK-QT
|
||||
which is documented here:
|
||||
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-doc/dev-guide-main.html
|
||||
|
||||
If you need to build Hamlib rather than use the Hamlib kit included in
|
||||
the JT-SDK the following recipe should help. Reasons for building
|
||||
Hamlib from source might include picking up the very latest patches or
|
||||
building a different branch that you wish to contribute to.
|
||||
|
||||
Hamlib optionally depends upon libusb-1.0, see "Building from Source"
|
||||
above for more details. If you wish to include support for the
|
||||
optional custom USB Hamlib rig drivers then you must install
|
||||
libusb-1.0 before building Hamlib. The package may be obtained from
|
||||
http://libusb.info/, install it in a convenient location like
|
||||
C:\Tools.
|
||||
|
||||
On Windows there is a complication in that the compilers used to build
|
||||
Qt and WSJT-X are the MinGW ones bundled with the Qt package but
|
||||
Hamlib needs to be build from an MSYS shell with the tools required to
|
||||
build an autotools project. This means that you need to tell the
|
||||
Hamlib configuration to use the Qt bundled MinGW compilers (if you
|
||||
don't then the thread support library use by Hamlib will be
|
||||
incompatible with that used by Qt and WSJT-X). So on Windows the
|
||||
Hamlib build recipe is something like:
|
||||
|
||||
In an MSYS shell:-
|
||||
|
||||
$ mkdir ~/hamib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
$ mkdir ../build
|
||||
$ cd ../build
|
||||
../src/configure --prefix=$HOME/hamlib-prefix \
|
||||
--disable-shared --enable-static \
|
||||
--without-cxx-binding --disable-winradio \
|
||||
CC=<path-to-Qt-MinGW-tools>/gcc \
|
||||
CXX=<path-to-Qt-MinGW-tools>/g++ \
|
||||
CFLAGS="-g -O2 -fdata-sections -ffunction-sections -I<path-to-libusb-1.0>/include" \
|
||||
LDFLAGS="-Wl,--gc-sections" \
|
||||
LIBUSB_LIBS="-L<path-to-libusb-1.0>/MinGW32/dll -lusb-1.0"
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
NOTE: <path-to-Qt-MinGQ-tools> should be substituted with the actual
|
||||
path to your Qt bundled tools e.g on my system it is
|
||||
C:\Tools\Qt\Tools\mingw530_32\bin
|
||||
|
||||
NOTE: <path-to-libusb-1.0> should be substituted with the actual path
|
||||
to your libusb-1.0 installation directory e.g. on my system it is
|
||||
C:\Tools\libusb-1.0.20
|
||||
|
||||
This will leave a Hamlib binary package installed at
|
||||
c:/Users/<user-name>/hamlib-prefix which is what needs to be on your
|
||||
CMAKE_PREFIX_PATH. On Windows you almost certainly will be using a
|
||||
CMake tool chain file and this is where you will need to specify the
|
||||
Hamlib binary location as one of the paths in CMAKE_PREFIX_PATH.
|
||||
|
||||
|
||||
Building from Source on Apple Mac
|
||||
=================================
|
||||
|
||||
These instructions are adapted from my Evernote page at:
|
||||
|
||||
https://www.evernote.com/pub/bsomervi/wsjt-xmacbuilds
|
||||
|
||||
There are several ways to get the required GNU and other open source
|
||||
tools and libraries installed, my preference is MacPorts because it is
|
||||
easy to use and does everything we need.
|
||||
|
||||
You will need Xcode, MacPorts, CMake and, Qt. The Xcode install
|
||||
instructions are included in the MacPorts documentation.
|
||||
|
||||
MacPorts
|
||||
--------
|
||||
Install MacPorts from instructions here:
|
||||
|
||||
http://www.macports.org/install.php
|
||||
|
||||
More detailed instructions are available in the documentation:
|
||||
|
||||
https://guide.macports.org
|
||||
|
||||
The ports that need to be installed are:
|
||||
|
||||
autoconf
|
||||
automake
|
||||
libtool
|
||||
pkgconfig
|
||||
texinfo
|
||||
gcc5
|
||||
fftw-3-single +gcc5
|
||||
asciidoc
|
||||
libusb-devel
|
||||
|
||||
These are installed by typing:
|
||||
|
||||
$ sudo port install autoconf automake \
|
||||
libtool pkgconfig texinfo gcc5 asciidoc \
|
||||
fftw-3-single +gcc5 libusb-devel
|
||||
|
||||
Once complete you should have all the tools required to build WSJT-X.
|
||||
|
||||
Uninstalling MacPorts
|
||||
---------------------
|
||||
If at some point you wish to remove the ports from your machine. The
|
||||
instructions are here:
|
||||
|
||||
https://guide.macports.org/#installing.macports.uninstalling .
|
||||
|
||||
Hamlib
|
||||
------
|
||||
First fetch hamlib from the repository, in this case my fork of Hamlib
|
||||
3 until the official repository has all the fixes we need:
|
||||
|
||||
$ mkdir -p ~/hamlib-prefix/build
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
|
||||
The integration branch is my system testing branch which has all my
|
||||
latest published changes.
|
||||
|
||||
To build:
|
||||
|
||||
$ cd ~/hamlib-prefix/build
|
||||
$ ../src/configure \
|
||||
--enable-static \
|
||||
--disable-shared \
|
||||
--disable-winradio \
|
||||
--prefix=$HOME/hamlib-prefix \
|
||||
CFLAGS="-g -O2 -mmacosx-version-min=10.7 -I/opt/local/include" \
|
||||
LIBUSB_LIBS="-L/opt/local/lib -lusb-1.0"
|
||||
$ make
|
||||
$ make install-strip
|
||||
|
||||
The above commands will build hamlib and install it into
|
||||
~/hamlib-prefix. If `make install-strip` fails, try `make install`.
|
||||
|
||||
|
||||
Qt
|
||||
--
|
||||
|
||||
NOTE: As of Qt v5.4 building Qt from source on Mac OS X is no longer
|
||||
necessary since the Qt team have switched to using the modern libc++
|
||||
Standard C++ Library for all distributable run time
|
||||
components. Instead you may simply download a binary installer for OS
|
||||
X 64-bit. The binary installer is here:
|
||||
|
||||
http://www.qt.io/download
|
||||
|
||||
The binary Qt distributions prior to Qt v5.4 from
|
||||
http://www.qt.io/download unfortunately are built to use the libstdc++
|
||||
C++ support library, WSJT-X uses a less geriatric C++ dialect which
|
||||
uses the libc++ C++ support library. This means that you need to
|
||||
build Qt from sources. This is not difficult but does take some time.
|
||||
|
||||
Download the Qt source tarball from
|
||||
http://www.qt.io/download-open-source/, the link is about half way
|
||||
down the page, you want the full sources tar ball shown as a 'tar.gz'
|
||||
link.
|
||||
|
||||
Unpack the sources and cd into the top level directory then type:
|
||||
|
||||
$ ./configure -prefix ~/local/qt-macx-clang -opensource \
|
||||
-confirm-license -platform macx-clang -silent -nomake tests \
|
||||
-nomake examples -sdk macosx10.10 -skip qtwebkit \
|
||||
-skip qtwebkit-examples -skip qtquick1 -skip qtconnectivity \
|
||||
-skip qtlocation -skip qtsensors -skip qtscript \
|
||||
-skip qtwebsockets -skip qtwebengine -skip qtwebchannel \
|
||||
-skip qtwayland -skip qtquickcontrols -skip qtdeclarative \
|
||||
-skip qtxmlpatterns -skip qtenginio
|
||||
$ make -j4
|
||||
$ make install
|
||||
|
||||
If you are building on 10.8 or don't have the 10.10 Mac SDK (Xcode 6)
|
||||
available, you can substitute '-sdk macosx10.9' above.
|
||||
|
||||
The build above will take a few hours to complete.
|
||||
|
||||
|
||||
CMake
|
||||
-----
|
||||
Although CMake is available via MacPorts I prefer to use the binary
|
||||
installer from cake.org as the MacPorts port doesn't include the
|
||||
graphical CMake tool cmake-gui which I find quite useful.
|
||||
|
||||
Fetch the latest CMake universal 64-bit DMG from
|
||||
http://www.cmake.org/download/ open the DMG then drag and drop the
|
||||
application bundle onto the supplied /Applications link.
|
||||
|
||||
To complete the install process you need to run the CMake-gui
|
||||
application as root from a terminal shell as follows:
|
||||
|
||||
$ sudo "/Applications/CMake.app/Contents/MacOS/cmake" --install
|
||||
|
||||
that installs the CMake command line tools which you can verify by
|
||||
typing into a terminal window:
|
||||
|
||||
$ cmake --version
|
||||
|
||||
If the install command above fails with a "No such file or directory"
|
||||
error, that probably means that /usr/local/bin does not exist. You can
|
||||
create it correctly with the following commands:
|
||||
|
||||
$ sudo mkdir -p /usr/local/bin
|
||||
$ sudo chmod 755 /usr/local/bin
|
||||
$ sudo chgrp wheel /usr/local/bin
|
||||
|
||||
and then retry the install command.
|
||||
|
||||
|
||||
WSJT-X
|
||||
------
|
||||
First fetch the source from the repository:
|
||||
|
||||
$ mkdir -p ~/wsjtx-prefix/build
|
||||
$ cd ~/wsjtx-prefix
|
||||
$ svn checkout svn://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx src
|
||||
|
||||
this links to the Subversion repository in a read-only fashion, if you
|
||||
intend to contribute to the project then you probably want to get a
|
||||
developer login and use a read-write checkout. Even if you don't it
|
||||
can be upgraded at a later date.
|
||||
|
||||
The checkout is of the latest code on the project trunk, i.e. the
|
||||
development branch. You can easily switch the checkout to another
|
||||
branch or even a tag if you want to build a prior published
|
||||
generation. For now we will build the latest development sources. To
|
||||
configure:
|
||||
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ FC=gfortran-mp-5 \
|
||||
cmake \
|
||||
-D CMAKE_PREFIX_PATH="~/Qt/5.7/clang_64;~/hamlib-prefix;/opt/local" \
|
||||
-D CMAKE_INSTALL_PREFIX=~/wsjtx-prefix \
|
||||
-D CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk \
|
||||
~/wsjtx-prefix/src
|
||||
|
||||
Substitute the Mac OS X SDK version you have installed in the above
|
||||
command if you have a different version from 10.11.
|
||||
|
||||
The CMAKE_PREFIX_PATH variable specifies where CMake should look first
|
||||
for other packages, the two elements may be different depending where
|
||||
you have installed Qt and what version you have (~/local/qt-macx-clang
|
||||
if you have built Qt from sources as described above in the Qt
|
||||
section) and where you installed Hamlib (i.e. the --prefix configure
|
||||
option above in the Hamlib section).
|
||||
|
||||
If you already have the fftw3-dev package installed on your system it
|
||||
may well get selected in preference to the one you built above in the
|
||||
MacPorts installation. It is unlikely that a prior installation of
|
||||
libfftw3f is correctly configured for use in a WSJT-X package, the
|
||||
CMAKE_PREFIX_PATH above is augmented with the MacPorts installation
|
||||
location (/opt/local) to ensure the correct libfftw3f.dylib and
|
||||
headers are located.
|
||||
|
||||
To build:
|
||||
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
which installs the WSJT-X application bundle into ~/wsjtx-prefix
|
||||
|
||||
|
||||
Updating and Rebuilding Hamlib
|
||||
==============================
|
||||
|
||||
From time to time new fixes will be pushed to the Hamlib fork
|
||||
repository integration branch. To pick them up type:
|
||||
|
||||
$ cd ~/hamlib-prefix/src
|
||||
$ git pull
|
||||
|
||||
To rebuild hamlib with the changed sources:
|
||||
|
||||
$ cd ~/hamlib-prefix/build
|
||||
$ make
|
||||
$ make install-strip
|
||||
|
||||
|
||||
Updating and Rebuilding WSJT-X
|
||||
==============================
|
||||
|
||||
To update to the latest sources type:
|
||||
|
||||
$ cd ~/wsjtx-prefix/src
|
||||
$ svn update
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
|
||||
73
|
||||
Bill
|
||||
G4WJS.
|
||||
Detailed instructions coming soon. In the meantime, follow INSTALL-WSJTX instructions, substituting the WSJT-X repository with this one.
|
||||
|
||||
@@ -0,0 +1,416 @@
|
||||
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Installing WSJT-X
|
||||
=================
|
||||
|
||||
Binary packages of WSJT-X are available from the project web site:
|
||||
|
||||
http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
|
||||
|
||||
Building from Source
|
||||
====================
|
||||
|
||||
On Linux systems some of the prerequisite libraries are available in
|
||||
the mainstream distribution repositories. They are Qt v5 and FFTW v3.
|
||||
For MS Windows see the section "Building from Source on MS Windows"
|
||||
below. For Apple Mac see the section "Building from Source on Apple
|
||||
Mac".
|
||||
|
||||
Qt v5, preferably v5.1 or later is required to build WSJT-X.
|
||||
|
||||
Qt v5 multimedia support and serial port is necessary as well as the
|
||||
core Qt v5 components, normally installing the Qt multimedia
|
||||
development package and Qt serialport development package are
|
||||
sufficient to pull in all the required Qt components and dependants as
|
||||
a single transaction. On some systems the Qt multimedia plugin
|
||||
component is separate in the distribution repository an it may also
|
||||
need installing.
|
||||
|
||||
The single precision FFTW v3 library libfftw3f is required along with
|
||||
the libfftw library development package. Normally installing the
|
||||
library development package pulls in all the FFTW v3 libraries
|
||||
including the single precision variant.
|
||||
|
||||
The Hamlib library optionally requires the libusb-1.0 library, if the
|
||||
development version (libusb-1.0-dev) is available Hamlib will
|
||||
configure its custom USB device back end drivers. Most rigs do not
|
||||
require this so normally you can choose not to install libusb-1.0-dev
|
||||
but if you have a SoftRock USB or similar SDR that uses a custom USB
|
||||
interface then it is required.
|
||||
|
||||
The Hamlib library is required. Currently WSJT-X needs to be built
|
||||
using a forked version of the Hamlib git master. This fork contains
|
||||
patches not yet accepted by the Hamlib development team which are
|
||||
essential for correct operation of WSJT-X. To build the Hamlib fork
|
||||
from sources something like the following recipe should suffice:
|
||||
|
||||
$ mkdir ~/hamlib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
$ mkdir ../build
|
||||
$ cd ../build
|
||||
$ ../src/configure --prefix=$HOME/hamlib-prefix \
|
||||
--disable-shared --enable-static \
|
||||
--without-cxx-binding --disable-winradio \
|
||||
CFLAGS="-g -O2 -fdata-sections -ffunction-sections" \
|
||||
LDFLAGS="-Wl,--gc-sections"
|
||||
$ make
|
||||
$ make install-strip
|
||||
|
||||
This will build a binary hamlib package located at ~/hamlib-prefix so
|
||||
you will need to add that to your CMAKE_PREFIX_PATH variable in your
|
||||
WSJT-X build. On Linux that is probably the only path you have on
|
||||
CMAKE_PREFIX_PATH unless you are using a locally installed Qt
|
||||
installation.
|
||||
|
||||
To get the sources either download and extract a source tarball from
|
||||
the project web site or preferably fetch the sources directly from the
|
||||
project's subversion repository. The project svn repository has a
|
||||
non-standard layout in that the WSJT-X project is not on the trunk,
|
||||
instead the main code line is in a branch at ^/branches/wsjtx
|
||||
|
||||
$ mkdir -p ~/wsjtx-prefix/build
|
||||
$ cd ~/wsjtx-prefix
|
||||
$ svn checkout svn://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx src
|
||||
|
||||
To build WSJT-X you will need CMake and asciidoc installed.
|
||||
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ cmake -D CMAKE_PREFIX_PATH=~/hamlib-prefix ../src
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
The recipe above will install into /usr by default, if you wish to
|
||||
install in you own directory you can add a prefix-path to the
|
||||
configure step like:
|
||||
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ cmake -D CMAKE_PREFIX_PATH=~/hamlib-prefix \
|
||||
-D CMAKE_INSTALL_PREFIX=~/wsjtx-prefix ../src
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
this will install WSJT-X at ~/wsjtx-prefix.
|
||||
|
||||
|
||||
Building from Source on MS Windows
|
||||
==================================
|
||||
|
||||
Because building on MS Windows is quite complicated there is an
|
||||
Software Development Kit available that provides all the prerequisite
|
||||
libraries and tools for building WSJT-X. This SDK is called JT-SDK-QT
|
||||
which is documented here:
|
||||
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-doc/dev-guide-main.html
|
||||
|
||||
If you need to build Hamlib rather than use the Hamlib kit included in
|
||||
the JT-SDK the following recipe should help. Reasons for building
|
||||
Hamlib from source might include picking up the very latest patches or
|
||||
building a different branch that you wish to contribute to.
|
||||
|
||||
Hamlib optionally depends upon libusb-1.0, see "Building from Source"
|
||||
above for more details. If you wish to include support for the
|
||||
optional custom USB Hamlib rig drivers then you must install
|
||||
libusb-1.0 before building Hamlib. The package may be obtained from
|
||||
http://libusb.info/, install it in a convenient location like
|
||||
C:\Tools.
|
||||
|
||||
On Windows there is a complication in that the compilers used to build
|
||||
Qt and WSJT-X are the MinGW ones bundled with the Qt package but
|
||||
Hamlib needs to be build from an MSYS shell with the tools required to
|
||||
build an autotools project. This means that you need to tell the
|
||||
Hamlib configuration to use the Qt bundled MinGW compilers (if you
|
||||
don't then the thread support library use by Hamlib will be
|
||||
incompatible with that used by Qt and WSJT-X). So on Windows the
|
||||
Hamlib build recipe is something like:
|
||||
|
||||
In an MSYS shell:-
|
||||
|
||||
$ mkdir ~/hamib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
$ mkdir ../build
|
||||
$ cd ../build
|
||||
../src/configure --prefix=$HOME/hamlib-prefix \
|
||||
--disable-shared --enable-static \
|
||||
--without-cxx-binding --disable-winradio \
|
||||
CC=<path-to-Qt-MinGW-tools>/gcc \
|
||||
CXX=<path-to-Qt-MinGW-tools>/g++ \
|
||||
CFLAGS="-g -O2 -fdata-sections -ffunction-sections -I<path-to-libusb-1.0>/include" \
|
||||
LDFLAGS="-Wl,--gc-sections" \
|
||||
LIBUSB_LIBS="-L<path-to-libusb-1.0>/MinGW32/dll -lusb-1.0"
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
NOTE: <path-to-Qt-MinGQ-tools> should be substituted with the actual
|
||||
path to your Qt bundled tools e.g on my system it is
|
||||
C:\Tools\Qt\Tools\mingw530_32\bin
|
||||
|
||||
NOTE: <path-to-libusb-1.0> should be substituted with the actual path
|
||||
to your libusb-1.0 installation directory e.g. on my system it is
|
||||
C:\Tools\libusb-1.0.20
|
||||
|
||||
This will leave a Hamlib binary package installed at
|
||||
c:/Users/<user-name>/hamlib-prefix which is what needs to be on your
|
||||
CMAKE_PREFIX_PATH. On Windows you almost certainly will be using a
|
||||
CMake tool chain file and this is where you will need to specify the
|
||||
Hamlib binary location as one of the paths in CMAKE_PREFIX_PATH.
|
||||
|
||||
|
||||
Building from Source on Apple Mac
|
||||
=================================
|
||||
|
||||
These instructions are adapted from my Evernote page at:
|
||||
|
||||
https://www.evernote.com/pub/bsomervi/wsjt-xmacbuilds
|
||||
|
||||
There are several ways to get the required GNU and other open source
|
||||
tools and libraries installed, my preference is MacPorts because it is
|
||||
easy to use and does everything we need.
|
||||
|
||||
You will need Xcode, MacPorts, CMake and, Qt. The Xcode install
|
||||
instructions are included in the MacPorts documentation.
|
||||
|
||||
MacPorts
|
||||
--------
|
||||
Install MacPorts from instructions here:
|
||||
|
||||
http://www.macports.org/install.php
|
||||
|
||||
More detailed instructions are available in the documentation:
|
||||
|
||||
https://guide.macports.org
|
||||
|
||||
The ports that need to be installed are:
|
||||
|
||||
autoconf
|
||||
automake
|
||||
libtool
|
||||
pkgconfig
|
||||
texinfo
|
||||
gcc5
|
||||
fftw-3-single +gcc5
|
||||
asciidoc
|
||||
libusb-devel
|
||||
|
||||
These are installed by typing:
|
||||
|
||||
$ sudo port install autoconf automake \
|
||||
libtool pkgconfig texinfo gcc5 asciidoc \
|
||||
fftw-3-single +gcc5 libusb-devel
|
||||
|
||||
Once complete you should have all the tools required to build WSJT-X.
|
||||
|
||||
Uninstalling MacPorts
|
||||
---------------------
|
||||
If at some point you wish to remove the ports from your machine. The
|
||||
instructions are here:
|
||||
|
||||
https://guide.macports.org/#installing.macports.uninstalling .
|
||||
|
||||
Hamlib
|
||||
------
|
||||
First fetch hamlib from the repository, in this case my fork of Hamlib
|
||||
3 until the official repository has all the fixes we need:
|
||||
|
||||
$ mkdir -p ~/hamlib-prefix/build
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
|
||||
The integration branch is my system testing branch which has all my
|
||||
latest published changes.
|
||||
|
||||
To build:
|
||||
|
||||
$ cd ~/hamlib-prefix/build
|
||||
$ ../src/configure \
|
||||
--enable-static \
|
||||
--disable-shared \
|
||||
--disable-winradio \
|
||||
--prefix=$HOME/hamlib-prefix \
|
||||
CFLAGS="-g -O2 -mmacosx-version-min=10.7 -I/opt/local/include" \
|
||||
LIBUSB_LIBS="-L/opt/local/lib -lusb-1.0"
|
||||
$ make
|
||||
$ make install-strip
|
||||
|
||||
The above commands will build hamlib and install it into
|
||||
~/hamlib-prefix. If `make install-strip` fails, try `make install`.
|
||||
|
||||
|
||||
Qt
|
||||
--
|
||||
|
||||
NOTE: As of Qt v5.4 building Qt from source on Mac OS X is no longer
|
||||
necessary since the Qt team have switched to using the modern libc++
|
||||
Standard C++ Library for all distributable run time
|
||||
components. Instead you may simply download a binary installer for OS
|
||||
X 64-bit. The binary installer is here:
|
||||
|
||||
http://www.qt.io/download
|
||||
|
||||
The binary Qt distributions prior to Qt v5.4 from
|
||||
http://www.qt.io/download unfortunately are built to use the libstdc++
|
||||
C++ support library, WSJT-X uses a less geriatric C++ dialect which
|
||||
uses the libc++ C++ support library. This means that you need to
|
||||
build Qt from sources. This is not difficult but does take some time.
|
||||
|
||||
Download the Qt source tarball from
|
||||
http://www.qt.io/download-open-source/, the link is about half way
|
||||
down the page, you want the full sources tar ball shown as a 'tar.gz'
|
||||
link.
|
||||
|
||||
Unpack the sources and cd into the top level directory then type:
|
||||
|
||||
$ ./configure -prefix ~/local/qt-macx-clang -opensource \
|
||||
-confirm-license -platform macx-clang -silent -nomake tests \
|
||||
-nomake examples -sdk macosx10.10 -skip qtwebkit \
|
||||
-skip qtwebkit-examples -skip qtquick1 -skip qtconnectivity \
|
||||
-skip qtlocation -skip qtsensors -skip qtscript \
|
||||
-skip qtwebsockets -skip qtwebengine -skip qtwebchannel \
|
||||
-skip qtwayland -skip qtquickcontrols -skip qtdeclarative \
|
||||
-skip qtxmlpatterns -skip qtenginio
|
||||
$ make -j4
|
||||
$ make install
|
||||
|
||||
If you are building on 10.8 or don't have the 10.10 Mac SDK (Xcode 6)
|
||||
available, you can substitute '-sdk macosx10.9' above.
|
||||
|
||||
The build above will take a few hours to complete.
|
||||
|
||||
|
||||
CMake
|
||||
-----
|
||||
Although CMake is available via MacPorts I prefer to use the binary
|
||||
installer from cake.org as the MacPorts port doesn't include the
|
||||
graphical CMake tool cmake-gui which I find quite useful.
|
||||
|
||||
Fetch the latest CMake universal 64-bit DMG from
|
||||
http://www.cmake.org/download/ open the DMG then drag and drop the
|
||||
application bundle onto the supplied /Applications link.
|
||||
|
||||
To complete the install process you need to run the CMake-gui
|
||||
application as root from a terminal shell as follows:
|
||||
|
||||
$ sudo "/Applications/CMake.app/Contents/MacOS/cmake" --install
|
||||
|
||||
that installs the CMake command line tools which you can verify by
|
||||
typing into a terminal window:
|
||||
|
||||
$ cmake --version
|
||||
|
||||
If the install command above fails with a "No such file or directory"
|
||||
error, that probably means that /usr/local/bin does not exist. You can
|
||||
create it correctly with the following commands:
|
||||
|
||||
$ sudo mkdir -p /usr/local/bin
|
||||
$ sudo chmod 755 /usr/local/bin
|
||||
$ sudo chgrp wheel /usr/local/bin
|
||||
|
||||
and then retry the install command.
|
||||
|
||||
|
||||
WSJT-X
|
||||
------
|
||||
First fetch the source from the repository:
|
||||
|
||||
$ mkdir -p ~/wsjtx-prefix/build
|
||||
$ cd ~/wsjtx-prefix
|
||||
$ svn checkout svn://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx src
|
||||
|
||||
this links to the Subversion repository in a read-only fashion, if you
|
||||
intend to contribute to the project then you probably want to get a
|
||||
developer login and use a read-write checkout. Even if you don't it
|
||||
can be upgraded at a later date.
|
||||
|
||||
The checkout is of the latest code on the project trunk, i.e. the
|
||||
development branch. You can easily switch the checkout to another
|
||||
branch or even a tag if you want to build a prior published
|
||||
generation. For now we will build the latest development sources. To
|
||||
configure:
|
||||
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ FC=gfortran-mp-5 \
|
||||
cmake \
|
||||
-D CMAKE_PREFIX_PATH="~/Qt/5.7/clang_64;~/hamlib-prefix;/opt/local" \
|
||||
-D CMAKE_INSTALL_PREFIX=~/wsjtx-prefix \
|
||||
-D CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk \
|
||||
~/wsjtx-prefix/src
|
||||
|
||||
Substitute the Mac OS X SDK version you have installed in the above
|
||||
command if you have a different version from 10.11.
|
||||
|
||||
The CMAKE_PREFIX_PATH variable specifies where CMake should look first
|
||||
for other packages, the two elements may be different depending where
|
||||
you have installed Qt and what version you have (~/local/qt-macx-clang
|
||||
if you have built Qt from sources as described above in the Qt
|
||||
section) and where you installed Hamlib (i.e. the --prefix configure
|
||||
option above in the Hamlib section).
|
||||
|
||||
If you already have the fftw3-dev package installed on your system it
|
||||
may well get selected in preference to the one you built above in the
|
||||
MacPorts installation. It is unlikely that a prior installation of
|
||||
libfftw3f is correctly configured for use in a WSJT-X package, the
|
||||
CMAKE_PREFIX_PATH above is augmented with the MacPorts installation
|
||||
location (/opt/local) to ensure the correct libfftw3f.dylib and
|
||||
headers are located.
|
||||
|
||||
To build:
|
||||
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
which installs the WSJT-X application bundle into ~/wsjtx-prefix
|
||||
|
||||
|
||||
Updating and Rebuilding Hamlib
|
||||
==============================
|
||||
|
||||
From time to time new fixes will be pushed to the Hamlib fork
|
||||
repository integration branch. To pick them up type:
|
||||
|
||||
$ cd ~/hamlib-prefix/src
|
||||
$ git pull
|
||||
|
||||
To rebuild hamlib with the changed sources:
|
||||
|
||||
$ cd ~/hamlib-prefix/build
|
||||
$ make
|
||||
$ make install-strip
|
||||
|
||||
|
||||
Updating and Rebuilding WSJT-X
|
||||
==============================
|
||||
|
||||
To update to the latest sources type:
|
||||
|
||||
$ cd ~/wsjtx-prefix/src
|
||||
$ svn update
|
||||
$ cd ~/wsjtx-prefix/build
|
||||
$ cmake --build .
|
||||
$ cmake --build . --target install
|
||||
|
||||
|
||||
73
|
||||
Bill
|
||||
G4WJS.
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <QHostAddress>
|
||||
#include <QColor>
|
||||
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "moc_MessageClient.cpp"
|
||||
@@ -232,7 +234,7 @@ void MessageClient::impl::heartbeat ()
|
||||
Message m("PING", "", QMap<QString, QVariant>{
|
||||
{"NAME", QVariant(QApplication::applicationName())},
|
||||
{"VERSION", QVariant(QApplication::applicationVersion())},
|
||||
{"UTC", QVariant(QDateTime::currentDateTimeUtc().toMSecsSinceEpoch())}
|
||||
{"UTC", QVariant(DriftingDateTime::currentDateTimeUtc().toMSecsSinceEpoch())}
|
||||
});
|
||||
writeDatagram (m.toJson(), server_, server_port_);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <QHostAddress>
|
||||
#include <QColor>
|
||||
|
||||
#include "udp_export.h"
|
||||
#include "Radio.hpp"
|
||||
|
||||
#include "pimpl_h.hpp"
|
||||
@@ -23,7 +22,7 @@ class QString;
|
||||
// applications that use the Qt framework. Other applications should
|
||||
// use this classes' implementation as a reference implementation.
|
||||
//
|
||||
class UDP_EXPORT MessageServer
|
||||
class MessageServer
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
@@ -96,7 +95,7 @@ public:
|
||||
Q_SIGNAL void error (QString const&) const;
|
||||
|
||||
private:
|
||||
class UDP_NO_EXPORT impl;
|
||||
class impl;
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace
|
||||
char const * const mode_names[] =
|
||||
{
|
||||
"All",
|
||||
"FT8CALL",
|
||||
"JS8",
|
||||
};
|
||||
std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
enum Mode
|
||||
{
|
||||
ALL, // matches with all modes
|
||||
FT8CALL,
|
||||
JS8,
|
||||
MODES_END_SENTINAL_AND_COUNT // this must be last
|
||||
};
|
||||
Q_ENUM (Mode)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "soundout.h"
|
||||
#include "commons.h"
|
||||
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
#include "moc_Modulator.cpp"
|
||||
|
||||
extern float gran(); // Noise generator (for tests only)
|
||||
@@ -49,7 +51,7 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
|
||||
{
|
||||
Q_ASSERT (stream);
|
||||
// Time according to this computer which becomes our base time
|
||||
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
|
||||
qint64 ms0 = DriftingDateTime::currentMSecsSinceEpoch() % 86400000;
|
||||
|
||||
if (m_state != Idle)
|
||||
{
|
||||
@@ -176,7 +178,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
||||
if(m_TRperiod==3) slowCwId=false;
|
||||
bool fastCwId=false;
|
||||
static bool bCwId=false;
|
||||
qint64 ms = QDateTime::currentMSecsSinceEpoch();
|
||||
qint64 ms = DriftingDateTime::currentMSecsSinceEpoch();
|
||||
float tsec=0.001*(ms % (1000*m_TRperiod));
|
||||
if(m_bFastMode and (icw[0]>0) and (tsec>(m_TRperiod-5.0))) fastCwId=true;
|
||||
if(!m_bFastMode) m_nspd=2560; // 22.5 WPM
|
||||
@@ -289,10 +291,6 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
||||
if (m_ic > i1) m_amp = 0.0;
|
||||
|
||||
sample=qRound(m_amp*qSin(m_phi));
|
||||
if(m_toneSpacing < 0) sample=qRound(m_amp*foxcom_.wave[m_ic]);
|
||||
|
||||
// if(m_ic < 100) qDebug() << "Mod C" << m_ic << m_amp << foxcom_.wave[m_ic] << sample;
|
||||
|
||||
samples = load(postProcessSample(sample), samples);
|
||||
++framesGenerated;
|
||||
++m_ic;
|
||||
|
||||
@@ -1,80 +1,35 @@
|
||||
# JS8Call
|
||||
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2001 - 2017 by Joe Taylor, K1JT.
|
||||
FT8 has taken over the airwaves as the digital communication mode for making QSOs over HF/VHF/UHF. The mode has been widely popular as the latest offering in K1JT’s WSJT-X application. FT8 is based on the same foundation as JT65, JT9, and WSPR modes for weak signal communication, but transmits faster with only slightly reduced sensitivity.
|
||||
|
||||
WSJT-X is a computer program designed to facilitate basic amateur
|
||||
radio communication using very weak signals. The first four letters in
|
||||
the program name stand for “Weak Signal communication by K1JT,” while
|
||||
the suffix “-X” indicates that WSJT-X started as an extended (and
|
||||
experimental) branch of the program WSJT.
|
||||
While FT8 is an incredibly robust weak signal mode, it is designed heavily to take advantage of short band openings on HF/VHF/UHF and only offers a minimal QSO framework. However, many operators are using these weak signal qualities to make successful QSOs on the HF bands where other modes fail.
|
||||
|
||||
WSJT-X Version 1.6 offers five protocols or “modes”: JT4, JT9, JT65
|
||||
WSPR, and Echo. The first three are designed for making reliable QSOs
|
||||
under extreme weak-signal conditions. They use nearly identical
|
||||
message structure and source encoding. JT65 was designed for EME
|
||||
(“moonbounce”) on the VHF/UHF bands and has also proven very effective
|
||||
for worldwide QRP communication on the HF bands. JT9 is optimized for
|
||||
the LF, MF, and lower HF bands. It is 2 dB more sensitive than JT65
|
||||
while using less than 10% of the bandwidth. JT4 offers a wide variety
|
||||
of tone spacings and has proved very effective for EME on microwave
|
||||
bands up to 24 GHz. All three of these modes use one-minute timed
|
||||
sequences of alternating transmission and reception, so a minimal QSO
|
||||
takes four to six minutes — two or three transmissions by each
|
||||
station, one sending in odd UTC minutes and the other even. On the HF
|
||||
bands, world-wide QSOs are possible using power levels of a few watts
|
||||
and compromise antennas. On VHF bands and higher, QSOs are possible
|
||||
(by EME and other propagation types) at signal levels 10 to 15 dB
|
||||
below those required for CW.
|
||||
JS8Call is an experiment to test the feasibility of a digital mode with the robustness of FT8, combined with a messaging and network protocol layer for weak signal communication on HF, using keyboard-to-keyboard style interface. JS8Call is heavily inspired by WSJT-X, Fldigi, and FSQCall and would not exist without the hard work and dedication of the many developers in the amateur radio community.
|
||||
|
||||
WSPR (pronounced “whisper”) stands for Weak Signal Propagation
|
||||
Reporter. The WSPR protocol was designed for probing potential
|
||||
propagation paths using low-power transmissions. WSPR messages
|
||||
normally carry the transmitting station’s callsign, grid locator, and
|
||||
transmitter power in dBm, and they can be decoded at signal-to-noise
|
||||
ratios as low as -28 dB in a 2500 Hz bandwidth. WSPR users with
|
||||
internet access can automatically upload their reception reports to a
|
||||
central database called {wsprnet} that provides a mapping facility,
|
||||
archival storage, and many other features.
|
||||
* Read more on the original design inspiration here: https://github.com/jsherer/js8call
|
||||
|
||||
Echo mode allows you to detect and measure your own lunar echoes, even
|
||||
if they are far below the audible threshold.
|
||||
|
||||
WSJT-X provides spectral displays for passbands up to 5 kHz, flexible
|
||||
rig control for nearly all modern radios used by amateurs, and a wide
|
||||
variety of special aids such as automatic Doppler tracking for EME
|
||||
QSOs and Echo testing. The program runs equally well on Windows,
|
||||
Macintosh, and Linux systems, and installation packages are available
|
||||
for all three platforms.
|
||||
|
||||
WSJT-X is an open-source project released under the GPL license (See
|
||||
COPYING). If you have programming or documentation skills or would
|
||||
like to contribute to the project in other ways, please make your
|
||||
interests known to the development team. The project’s source-code
|
||||
repository can be found at https://sourceforge.net/projects/wsjt, and
|
||||
most communication among the developers takes place on the email
|
||||
reflector https://sourceforge.net/p/wsjt/mailman. User-level
|
||||
questions and answers, and general communication among users is found
|
||||
on the https://groups.yahoo.com/neo/groups/wsjtgroup/info email
|
||||
reflector.
|
||||
* For release announcements and discussion, join the JS8Call mailing list here: https://groups.io/g/js8call
|
||||
|
||||
|
||||
Project web site:
|
||||
# Notice
|
||||
|
||||
http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
JS8Call is a derivative of the WSJT-X application, restructured and redesigned for message passing using FT8 modulation. It is not supported by nor endorsed by the WSJT-X development group. While the WSJT-X group maintains copyright over the original work and code, JS8Call is a derivative work licensed under and in accordance with the terms of the GPLv3 license. The source code modifications are public and can be found in this repository: https://bitbucket.org/widefido/wsjtx/
|
||||
|
||||
Project mailing list (shared with other applications from the same
|
||||
team):
|
||||
|
||||
https://groups.yahoo.com/neo/groups/wsjtgroup
|
||||
# History
|
||||
|
||||
* July 6, 2017 - The initial idea of using a modification to the FT8 protocol to support long-form QSOs was developed by Jordan, KN4CRD, and submitted to the WSJT-X mailing list: https://sourceforge.net/p/wsjt/mailman/message/35931540/
|
||||
* August 31, 2017 - Jordan, KN4CRD, did a little development and modified WSJT-X to support long-form QSOs using the existing FT8 protocol: https://sourceforge.net/p/wsjt/mailman/message/36020051/ He sent a video example to the WSJT-X group: https://widefido.wistia.com/medias/7bb1uq62ga
|
||||
* January 8, 2018 - Jordan, KN4CRD, started working on the design of a long-form QSO application built on top of FT8 with a redesigned interface.
|
||||
* February 9, 2018 - Jordan, KN4CRD, submitted question to the WSJT-X group to see if there was any interest in pursuing the idea: https://sourceforge.net/p/wsjt/mailman/message/36221549/
|
||||
* February 10, 2018 - Jordan KN4CRD, Julian OH8STN, John N0JDS, and the Portable Digital QRP group did an experiment using FSQ. The idea of JS8Call, combining FT8, long-form QSOs, and FSQCall like features was born.
|
||||
* February 11, 2018 - Jordan, KN4CRD, inquired about the idea of integrating long-form messages into WSJT-X: https://sourceforge.net/p/wsjt/mailman/message/36223372/
|
||||
* February 12, 2018 - Joe Taylor, K1JT, wrote back: https://sourceforge.net/p/wsjt/mailman/message/36224507/ saying that “Please don't let my comment discourage you from proceeding as you wish, toward something new.”
|
||||
* March 4, 2018 - Jordan, KN4CRD, published a design document for JS8Call: https://github.com/jsherer/js8call
|
||||
* July 6, 2018 - Version 0.0.1 of JS8Call released to the development group
|
||||
* July 15, 2018 - Version 0.1 released - a dozen testers
|
||||
* July 21, 2018 - Version 0.2 released - 75 testers
|
||||
* July 27, 2018 - Version 0.3 released - 150 testers
|
||||
* August 12, 2018 - Version 0.4 released - (“leaked” on QRZ) - 500 testers
|
||||
* September 2, 2018 - Version 0.5 released - 3000 testers
|
||||
* September 14, 2018 - Version 0.6 released - 5000 testers
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <QLocale>
|
||||
#include <QList>
|
||||
|
||||
#include "udp_export.h"
|
||||
|
||||
class QVariant;
|
||||
class QString;
|
||||
|
||||
@@ -26,7 +24,7 @@ namespace Radio
|
||||
//
|
||||
// Qt type registration
|
||||
//
|
||||
void UDP_NO_EXPORT register_types ();
|
||||
void register_types ();
|
||||
|
||||
//
|
||||
// Frequency type conversion.
|
||||
@@ -34,27 +32,27 @@ namespace Radio
|
||||
// QVariant argument is convertible to double and is assumed to
|
||||
// be scaled by (10 ** -scale).
|
||||
//
|
||||
Frequency UDP_EXPORT frequency (QVariant const&, int scale,
|
||||
Frequency frequency (QVariant const&, int scale,
|
||||
bool * ok = nullptr, QLocale const& = QLocale ());
|
||||
FrequencyDelta UDP_EXPORT frequency_delta (QVariant const&, int scale,
|
||||
FrequencyDelta frequency_delta (QVariant const&, int scale,
|
||||
bool * ok = nullptr, QLocale const& = QLocale ());
|
||||
|
||||
//
|
||||
// Frequency type formatting
|
||||
//
|
||||
QString UDP_EXPORT frequency_MHz_string (Frequency, QLocale const& = QLocale ());
|
||||
QString UDP_EXPORT frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
|
||||
QString UDP_EXPORT pretty_frequency_MHz_string (Frequency, QLocale const& = QLocale ());
|
||||
QString UDP_EXPORT pretty_frequency_MHz_string (double, int scale, QLocale const& = QLocale ());
|
||||
QString UDP_EXPORT pretty_frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
|
||||
QString frequency_MHz_string (Frequency, QLocale const& = QLocale ());
|
||||
QString frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
|
||||
QString pretty_frequency_MHz_string (Frequency, QLocale const& = QLocale ());
|
||||
QString pretty_frequency_MHz_string (double, int scale, QLocale const& = QLocale ());
|
||||
QString pretty_frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ());
|
||||
|
||||
//
|
||||
// Callsigns
|
||||
//
|
||||
bool UDP_EXPORT is_callsign (QString const&);
|
||||
bool UDP_EXPORT is_compound_callsign (QString const&);
|
||||
QString UDP_EXPORT base_callsign (QString);
|
||||
QString UDP_EXPORT effective_prefix (QString);
|
||||
bool is_callsign (QString const&);
|
||||
bool is_compound_callsign (QString const&);
|
||||
QString base_callsign (QString);
|
||||
QString effective_prefix (QString);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE (Radio::Frequency);
|
||||
|
||||
@@ -1,410 +0,0 @@
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Copyright 2001 - 2018 by Joe Taylor, K1JT.
|
||||
|
||||
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.1
|
||||
June 1, 2018
|
||||
-----------------------------
|
||||
|
||||
This critical bug fix release repairs an unintended restriction in the FT8
|
||||
DXpedition mode. It supersedes v1.9.0 and must be used for DXpedition Fox
|
||||
operators.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0
|
||||
May 28, 2018
|
||||
-----------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.9.0-rc4 include the following:
|
||||
- Display in the right text window of MSK144 messages addressed to
|
||||
"MyCall" has been restored.
|
||||
|
||||
- Fox is not allowed to transmit in any of the default FT8 sub-bands.
|
||||
|
||||
- Fox can now work Hounds using compound callsigns.
|
||||
|
||||
- Fox can now transmit free-text messages (and any standard FT8 message)
|
||||
by using Tab 1 or Tab 2.
|
||||
|
||||
- Added a checkbox to enable more frequent programmed CQs by Fox.
|
||||
Default is OFF.
|
||||
|
||||
- Alt+N keyboard shortcut has been restored.
|
||||
|
||||
- MacOS program crash on unexpected decode request has been fixed.
|
||||
|
||||
|
||||
- Several minor bug fixes and added convenience features.
|
||||
|
||||
- Hamlib, support for TRXManger added.
|
||||
|
||||
- Hamlib, improved support for flrig.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0-rc4
|
||||
April 30, 2018
|
||||
---------------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.9.0-rc3 include the following:
|
||||
|
||||
- Corrected a number of flaws in Fox and Hound behavior, FT8
|
||||
DXpedition Mode
|
||||
|
||||
- Decoded CQ calls where a prefix has been used as a suffix should
|
||||
have the DXCC entity name assigned correctly in almost all cases
|
||||
|
||||
- Improved AFC capability for the wider JT65 sub-modes to help with
|
||||
drifting signals
|
||||
|
||||
- Better support for macOS using hi-DPI Retina displays
|
||||
|
||||
- New UDP message that allows external applications to highlight
|
||||
decoded callsigns
|
||||
|
||||
- Main-screen geometry and state of the "splitter" setting between its
|
||||
two text windows is now properly restored after program restart.
|
||||
|
||||
- New simulator jt49sim[.exe] replaces jt4sim and jt9sim
|
||||
|
||||
- Correct S/N measurements for the JT9 slow/wide submodes
|
||||
|
||||
- Other minor bug fixes
|
||||
|
||||
- Updated copy of cty.dat
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0-rc3
|
||||
March 18, 2018
|
||||
---------------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.9.0-rc2 include the following:
|
||||
|
||||
- Corrected a number of flaws in Fox behavior, FT8 DXpedition Mode
|
||||
|
||||
- Allow Hounds to use compound callsigns
|
||||
|
||||
- Write debugging information to FoxQSO.txt.
|
||||
|
||||
- Fix the "Blue Decode Button" bug
|
||||
|
||||
- Allow partial processing of incoming UDP Reply messages so that
|
||||
non-CQ/QRZ decodes can be processed. The processing is the same as
|
||||
double-clicking the same decoded message within WSJT-X except that
|
||||
"Enable Tx" will not be enabled.
|
||||
|
||||
- Send DX grid locator to wsjt_status.txt, for use by applications like
|
||||
PstRotatorAZ
|
||||
|
||||
- Correct the display of DXCC status of KG4 calls
|
||||
|
||||
- Updated copy of cty.dat
|
||||
|
||||
- Updates to documentation
|
||||
|
||||
- Other minor bug fixes
|
||||
|
||||
- This release contains updated Hamlib functionality including changes
|
||||
to the Yaesu FT-817 back end that allows the uBITx kit transceiver
|
||||
to be CAT controlled by WSJT-X.
|
||||
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.9.0-rc2
|
||||
February 26, 2018
|
||||
---------------------------------
|
||||
|
||||
Changes from WSJT-X Version 1.8.0 include the following:
|
||||
|
||||
- New FT8 DXpedition Mode to facilitate high QSO rates in pileup
|
||||
situations
|
||||
|
||||
- Decoding improvements for JT65 mode, including a priori (AP)
|
||||
decoding when VHF/UHF/Microwave features are enabled
|
||||
|
||||
- Optional Auto-Sequencing in JT4, JT9, and JT65 when
|
||||
VHF/UHF/Microwave features are enabled
|
||||
|
||||
- Better suppression of low-confidence false decodes generated by AP
|
||||
decoding in FT8 mode
|
||||
|
||||
- Improved decoding performance for WSPR mode, especially effective at
|
||||
LF and MF
|
||||
|
||||
- Minor adjustments to auto-sequencing behavior
|
||||
|
||||
- More flexible Doppler control features for EME
|
||||
|
||||
- Improved waterfall sensitivity for very weak signals
|
||||
|
||||
- Automatic real-time forwarding of logged information to N1MM Logger+
|
||||
|
||||
- Expanded and improved UDP messages sent to companion programs
|
||||
|
||||
- Bug fixes and other minor tweaks to user interface
|
||||
|
||||
A primary purpose of this beta release is to allow field testing of
|
||||
FT8 DXpedition Mode. Instructions for this mode are posted here:
|
||||
|
||||
http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf
|
||||
|
||||
Contacts in FT8 DXpedition Mode must use WSJT-X v1.9.0 at both ends of
|
||||
the QSO. Please report any anomalous behavior to email list
|
||||
wsjt-devel@lists.sourceforge.net. You must be a subscriber in order
|
||||
to post there.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0
|
||||
October 27, 2017
|
||||
-----------------------------
|
||||
|
||||
This is the full General Availability release of WSJT-X Version 1.8.0.
|
||||
|
||||
Changes from WSJT-X Version 1.8.0-rc3 are very minor:
|
||||
|
||||
- Right-click on the Wide Graph now pops up a Context Menu. Select
|
||||
the item *Set Rx & Tx Offset* to complete a one-handed setting of
|
||||
both red and green frequency markers.
|
||||
|
||||
- Several clarifications and additions to Tool Tips and the User Guide.
|
||||
|
||||
|
||||
We recommend that all users should upgrade to WSJT-X Version 1.8.0.
|
||||
|
||||
If you upgrade from v1.8.0-rc1 it may be necessary to do a one-time
|
||||
reset of the default list of suggested operating frequencies. Go to
|
||||
*File->Settings->Frequencies*, right click on the table and select
|
||||
*Reset*.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0-rc3
|
||||
October 16, 2017
|
||||
---------------------------------
|
||||
|
||||
Most (but not all) changes since Version 1.8.0-rc2 involve user
|
||||
control of the increasingly popular FT8 mode. The "RC3" release also
|
||||
includes minor bug fixes and updates to the WSJT-X User Guide.
|
||||
|
||||
The following list includes all of the more important changes:
|
||||
|
||||
- New optimization of GUI for simplex and split behavior in FT8 mode.
|
||||
|
||||
1. Checkbox "Lock Tx Freq" on main window is relabeled "Hold Tx Freq".
|
||||
|
||||
2. Double-clicking on decoded messages that do not contain your own
|
||||
call moves both Rx and Tx frequencies. If the first callsign is
|
||||
your own call, only Rx freq moves.
|
||||
|
||||
3. Double-clicking on decoded messages moves the Rx frequency. If
|
||||
"Hold Tx Freq" is checked, Tx frequency is moved only if CTRL was
|
||||
held down.
|
||||
|
||||
4. Clicking on the waterfall moves Rx and Tx frequencies as
|
||||
before: Rx only on a simple click, Tx only on SHIFT-click, and
|
||||
both on CTRL-click. This happens even if "Hold Tx Freq" is
|
||||
checked.
|
||||
|
||||
- Add a semi-automated "FreqCal" procedure: see *Solve for calibration
|
||||
parameters* on the Tools menu.
|
||||
|
||||
- Improv auto-sequencing behavior: stop and on-frequency
|
||||
transmission if a called station comes back to someone else.
|
||||
|
||||
- Improve S/N estimation in some situations involving QRM.
|
||||
|
||||
- Fix an initialization issue with user-modified application fonts.
|
||||
|
||||
- Fix an issue with Tx5 message generation with Type 2 compound calls.
|
||||
|
||||
- Enhance and improve the ADIF parser of logbook records. Update
|
||||
the band limits as per ADIF 3.0.6 specification.
|
||||
|
||||
- Increase the FT8 DT range to +/- 2.5 s.
|
||||
|
||||
- Do not allow window manager events to close the astronomical data
|
||||
window.
|
||||
|
||||
- Add an "Erase" item to the context (right-click) menu for decoded
|
||||
text.
|
||||
|
||||
- Extend UDP messages with an "off air" boolean field indicating that
|
||||
the decode was derived from a .WAV file playback rather than an on air
|
||||
reception.
|
||||
|
||||
- Extend reference applications to use the new off air decode message
|
||||
field.
|
||||
|
||||
- Improve performance of FT8 decoder, especially for overlapping
|
||||
signals.
|
||||
|
||||
- Allow specialized use of "x2 Tone Spacing" in FT8 and slow JT9
|
||||
modes.
|
||||
|
||||
- Move "NA VHF Contest Mode" checkbox to main screen. Query the
|
||||
operator if d > 10000 km.
|
||||
|
||||
- Adjust UI to improve portability with font size changes and between
|
||||
platforms.
|
||||
|
||||
- Extend UDP Reply message to support keyboard modifiers. This allows
|
||||
UDP servers to emulate keyboard modified double-clicks on decoded
|
||||
messages, e.g. ALT+double-click for replying to a CQ or QRZ call
|
||||
without changing ones Tx frequency offset.
|
||||
|
||||
- Update the cty.dat file (21st Sept 2017).
|
||||
|
||||
- Ensure that Fast Graph is properly initialized.
|
||||
|
||||
- Better handling of worked before and country name display. Appended
|
||||
text is added at a fixed column unless the message overlaps in which
|
||||
case the appended information floats to the right.
|
||||
|
||||
- Restore printing of MSK144 decode quality information.
|
||||
|
||||
- Display Echo Graph automatically when Echo mode is started.
|
||||
|
||||
- Fix a bug that prevented double-click on a JT65 EME-style "OOO"
|
||||
message from populating the Tx message boxes.
|
||||
|
||||
- Fixed behavior with double-click on 'CQ <AA-ZZ> <call> <grid>.'
|
||||
|
||||
- Update the "blank line" divider with band ID at 4*TRperiod/5.
|
||||
|
||||
- Fix cty.dat lookups that were not honouring exact match flags
|
||||
|
||||
- Add some further Copyright protections.
|
||||
|
||||
- Fix a bug involving "firstcall contains mycall" but not equal to mycall.
|
||||
|
||||
- Fix an issue with editing IARU regions in the working frequencies table.
|
||||
|
||||
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0-rc2
|
||||
September 2, 2017
|
||||
---------------------------------
|
||||
|
||||
Implementation of FT8 and its auto-sequencing feature is now more
|
||||
capable and more polished. The decoder is faster and better: it now
|
||||
includes signal subtraction, multi-pass decoding, and the use of
|
||||
accumulated "a priori" information as a QSO progresses. Sensitivity
|
||||
extends downward as far as -24 dB in some circumstances. Overlapping
|
||||
signals 2 and 3 deep are frequently decoded at essentially the same
|
||||
frequency. On a crowded band we sometimes see more than 30 decodes in
|
||||
a single 15-second interval, over a 2 kHz window. The North American
|
||||
VHF Contesting Mode has been extended to include both FT8 and MSK144
|
||||
modes.
|
||||
|
||||
The "RC2" release also includes many minor bug fixes and an
|
||||
extensively updated WSJT-X User Guide.
|
||||
|
||||
Depending on what code revision you upgrade from, it may be necessary
|
||||
to do a one-time reset of the default list of suggested operating
|
||||
frequencies. Go to *File->Settings->Frequencies*, right click on
|
||||
the table and select *Reset*.
|
||||
|
||||
|
||||
Release: WSJT-X Version 1.8.0
|
||||
-----------------------------
|
||||
|
||||
NEW FEATURES IN WSJT-X Version 1.8.0
|
||||
------------------------------------
|
||||
|
||||
1. New mode called FT8: sensitivity down to -20 dB on the AWGN
|
||||
channel; QSOs 4 times faster than JT65 or JT9; auto-sequencing
|
||||
includes an option to respond automatically to first decoded
|
||||
reply to your CQ.
|
||||
|
||||
2. New mode for accurate Frequency Calibration of your radio.
|
||||
|
||||
3. Improved performance of decoders for JT65, QRA64, and MSK144.
|
||||
MSK144 includes facilities for amplitide and phase equalization
|
||||
and an "SWL" mode for short-format messages.
|
||||
|
||||
4. Options to minimize screen space used by Main and Wide Graph
|
||||
windows.
|
||||
|
||||
5. Enhanced management scheme for table of operating frequencies, and
|
||||
a new set of default frequencies specific to the three IARU
|
||||
Regions.
|
||||
|
||||
6. Improved CAT control for many rigs, including those controlled
|
||||
through Commander or OmniRig.
|
||||
|
||||
7. New keyboard shortcuts to set "Tx even/1st" ON or OFF.
|
||||
|
||||
8. A number of (mostly minor) bug fixes and tweaks to the user
|
||||
interface. For example: new behavior for the audio level slider;
|
||||
correctly logged QSO start times in certain situations; correct
|
||||
control of FT-891/991 and some other radios via rigctld.
|
||||
|
||||
At the time of the v1.8.0-rc1 release the following tasks are yet to
|
||||
be completed:
|
||||
|
||||
1. Updates to WSJT-X User Guide.
|
||||
2. Sample files for FT8.
|
||||
3. Enhanced decoding using AP ("a priori") information.
|
||||
4. Signal subtraction and multi-pass decoding.
|
||||
5. Option to Auto-respond to the weakest responder to your CQ.
|
||||
|
||||
|
||||
Installation packages for Windows, Linux, OS X, and Raspbian can be
|
||||
downloaded from the WSJT web site:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
|
||||
Please send bug reports to either wsjtgroup@yahoogroups.com or
|
||||
wsjt-devel@lists.sourceforge.net. Such reports should include a full
|
||||
prescription of steps to reproduce the undesired behavior. You must
|
||||
be a subscriber to post to either of these lists.
|
||||
|
||||
|
||||
Brief Description of the FT8 Protocol
|
||||
-------------------------------------
|
||||
|
||||
WSJT-X Version 1.8.0 includes a new mode called FT8, developed by K9AN
|
||||
and K1JT. The mode name "FT8" stands for "Franke and Taylor, 8-FSK
|
||||
modulation". FT8 uses 15-second T/R sequences and provides 50% or
|
||||
better decoding probability down to -20 dB on an AWGN channel. An
|
||||
auto-sequencing facility includes an option to respond automatically
|
||||
to the first decoded reply to your CQ. FT8 QSOs are 4 times faster
|
||||
than those made with JT65 or JT9. FT8 is an excellent mode for HF
|
||||
DXing and for situations like multi-hop E_s on 6 meters, where deep
|
||||
QSB may make fast and reliable completion of QSOs desirable.
|
||||
|
||||
Some important characteristics of FT8:
|
||||
|
||||
- T/R sequence length: 15 s
|
||||
- Message length: 75 bits + 12-bit CRC
|
||||
- FEC code: LDPC(174,87)
|
||||
- Modulation: 8-FSK, tone spacing 6.25 Hz
|
||||
- Constant-envelope waveform
|
||||
- Occupied bandwidth: 50 Hz
|
||||
- Synchronization: 7x7 Costas arrays at start, middle, and end
|
||||
- Transmission duration: 79*1920/12000 = 12.64 s
|
||||
- Decoding threshold: -20 dB; several dB lower with AP decoding
|
||||
- Multi-decoder finds and decodes all FT8 signals in passband
|
||||
- Optional auto-sequencing and auto-reply to a CQ response
|
||||
- Operational behavior similar to JT9, JT65
|
||||
|
||||
We plan to implement signal subtraction, two-pass decoding, and use of
|
||||
a priori (AP) information in the decoder. These features are not yet
|
||||
activated in v1.8.0.
|
||||
|
||||
We haven't yet finalized what the three extra bits in the message
|
||||
payload will be used for. Suggestions are welcome!
|
||||
|
||||
-- Joe, K1JT, for the WSJT Development Team
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
#include "SampleDownloader.hpp"
|
||||
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
#include "SettingsGroup.hpp"
|
||||
#include "SampleDownloader/Directory.hpp"
|
||||
#include "MessageBox.hpp"
|
||||
|
||||
#include "moc_SampleDownloader.cpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * const title = "Download Samples";
|
||||
}
|
||||
|
||||
class SampleDownloader::impl final
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit impl (QSettings * settings, Configuration const *, QNetworkAccessManager *, QWidget * parent);
|
||||
~impl () {save_window_state ();}
|
||||
|
||||
void refresh ()
|
||||
{
|
||||
show ();
|
||||
raise ();
|
||||
activateWindow ();
|
||||
directory_.refresh (http_only_check_box_.isChecked ());
|
||||
}
|
||||
|
||||
protected:
|
||||
void closeEvent (QCloseEvent * e) override
|
||||
{
|
||||
save_window_state ();
|
||||
QDialog::closeEvent (e);
|
||||
}
|
||||
|
||||
private:
|
||||
void save_window_state ()
|
||||
{
|
||||
SettingsGroup g (settings_, title);
|
||||
settings_->setValue ("geometry", saveGeometry ());
|
||||
settings_->setValue ("SamplesURL", url_line_edit_.text ());
|
||||
settings_->setValue ("HTTPOnly", http_only_check_box_.isChecked ());
|
||||
}
|
||||
|
||||
Q_SLOT void button_clicked (QAbstractButton *);
|
||||
|
||||
QSettings * settings_;
|
||||
Directory directory_;
|
||||
QGridLayout main_layout_;
|
||||
QVBoxLayout left_layout_;
|
||||
QDialogButtonBox button_box_;
|
||||
QWidget details_widget_;
|
||||
QFormLayout details_layout_;
|
||||
QLineEdit url_line_edit_;
|
||||
QCheckBox http_only_check_box_;
|
||||
};
|
||||
|
||||
#include "SampleDownloader.moc"
|
||||
|
||||
SampleDownloader::SampleDownloader (QSettings * settings, Configuration const * configuration
|
||||
, QNetworkAccessManager * network_manager, QWidget * parent)
|
||||
: m_ {settings, configuration, network_manager, parent}
|
||||
{
|
||||
}
|
||||
|
||||
SampleDownloader::~SampleDownloader ()
|
||||
{
|
||||
}
|
||||
|
||||
void SampleDownloader::show ()
|
||||
{
|
||||
m_->refresh ();
|
||||
}
|
||||
|
||||
SampleDownloader::impl::impl (QSettings * settings
|
||||
, Configuration const * configuration
|
||||
, QNetworkAccessManager * network_manager
|
||||
, QWidget * parent)
|
||||
: QDialog {parent, Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint}
|
||||
, settings_ {settings}
|
||||
, directory_ {configuration, network_manager}
|
||||
, button_box_ {QDialogButtonBox::Close, Qt::Vertical}
|
||||
{
|
||||
setWindowTitle (windowTitle () + ' ' + tr (title));
|
||||
resize (500, 600);
|
||||
{
|
||||
SettingsGroup g {settings_, title};
|
||||
restoreGeometry (settings_->value ("geometry", saveGeometry ()).toByteArray ());
|
||||
url_line_edit_.setText (settings_->value ("SamplesURL", PROJECT_SAMPLES_URL).toString ());
|
||||
http_only_check_box_.setChecked (settings_->value ("HTTPOnly", false).toBool ());
|
||||
directory_.url_root (url_line_edit_.text ());
|
||||
}
|
||||
|
||||
setWindowTitle (QApplication::applicationName () + " - " + tr ("Download Samples"));
|
||||
|
||||
button_box_.button (QDialogButtonBox::Close)->setDefault (true);
|
||||
button_box_.addButton ("&Abort", QDialogButtonBox::DestructiveRole);
|
||||
button_box_.addButton ("&Refresh", QDialogButtonBox::ResetRole);
|
||||
left_layout_.addWidget (&directory_);
|
||||
|
||||
auto details_button = button_box_.addButton ("&Details", QDialogButtonBox::HelpRole);
|
||||
details_button->setCheckable (true);
|
||||
details_widget_.hide ();
|
||||
details_layout_.setMargin (0);
|
||||
details_layout_.addRow ("Base URL for samples:", &url_line_edit_);
|
||||
details_layout_.addRow ("Only use HTTP:", &http_only_check_box_);
|
||||
http_only_check_box_.setToolTip ("Check this is you get SSL/TLS errors");
|
||||
details_widget_.setLayout (&details_layout_);
|
||||
|
||||
main_layout_.addLayout (&left_layout_, 0, 0);
|
||||
main_layout_.addWidget (&button_box_, 0, 1);
|
||||
main_layout_.addWidget (&details_widget_, 1, 0, 1, 2);
|
||||
main_layout_.setRowStretch (1, 2);
|
||||
setLayout (&main_layout_);
|
||||
|
||||
connect (&button_box_, &QDialogButtonBox::clicked, this, &SampleDownloader::impl::button_clicked);
|
||||
connect (details_button, &QAbstractButton::clicked, &details_widget_, &QWidget::setVisible);
|
||||
connect (&url_line_edit_, &QLineEdit::editingFinished, [this] () {
|
||||
if (directory_.url_root (url_line_edit_.text ()))
|
||||
{
|
||||
directory_.refresh (http_only_check_box_.isChecked ());
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("Input Error"), tr ("Invalid URL format"));
|
||||
}
|
||||
});
|
||||
connect (&http_only_check_box_, &QAbstractButton::toggled, [this] (bool checked) {
|
||||
directory_.refresh (checked);
|
||||
});
|
||||
}
|
||||
|
||||
void SampleDownloader::impl::button_clicked (QAbstractButton * button)
|
||||
{
|
||||
switch (button_box_.buttonRole (button))
|
||||
{
|
||||
case QDialogButtonBox::RejectRole:
|
||||
hide ();
|
||||
break;
|
||||
|
||||
case QDialogButtonBox::DestructiveRole:
|
||||
directory_.abort ();
|
||||
break;
|
||||
|
||||
case QDialogButtonBox::ResetRole:
|
||||
directory_.refresh (http_only_check_box_.isChecked ());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef SAMPLE_DOWNLOADER_HPP__
|
||||
#define SAMPLE_DOWNLOADER_HPP__
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "pimpl_h.hpp"
|
||||
|
||||
class QSettings;
|
||||
class QWidget;
|
||||
class QNetworkAccessManager;
|
||||
class Configuration;
|
||||
|
||||
//
|
||||
// SampleDownloader - A Dialog to maintain sample files
|
||||
//
|
||||
// This uses a Qt Dialog window that contains a tree view of the
|
||||
// available sample files on a web or ftp server. The files can be
|
||||
// installed locally by ticking a check box or removed from the local
|
||||
// machine by un-ticking the check boxes.
|
||||
//
|
||||
// The class requires a pointer to an open QSettings instance where it
|
||||
// will save its persistent state, a pointer to a WSJT-X Configuration
|
||||
// instance that is used to obtain configuration information like the
|
||||
// current file save location and, a pointer to a
|
||||
// QNetworkAccessManager instance which is used for network requests.
|
||||
//
|
||||
// An instance of SampleDownloader need not be destroyed after use,
|
||||
// just call SampleDownloader::show() to make the dialog visible
|
||||
// again.
|
||||
//
|
||||
class SampleDownloader final
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
SampleDownloader (QSettings * settings
|
||||
, Configuration const *
|
||||
, QNetworkAccessManager *
|
||||
, QWidget * parent = nullptr);
|
||||
~SampleDownloader ();
|
||||
|
||||
Q_SLOT void show ();
|
||||
|
||||
private:
|
||||
class impl;
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,319 +0,0 @@
|
||||
#include "Directory.hpp"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QHeaderView>
|
||||
#include <QStringList>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QAuthenticator>
|
||||
#include <QNetworkReply>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QTreeWidgetItemIterator>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "Configuration.hpp"
|
||||
#include "DirectoryNode.hpp"
|
||||
#include "FileNode.hpp"
|
||||
#include "revision_utils.hpp"
|
||||
#include "MessageBox.hpp"
|
||||
|
||||
#include "moc_Directory.cpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * samples_dir_name = "samples";
|
||||
QString const contents_file_name = "contents_" + version (false) + ".json";
|
||||
}
|
||||
|
||||
Directory::Directory (Configuration const * configuration
|
||||
, QNetworkAccessManager * network_manager
|
||||
, QWidget * parent)
|
||||
: QTreeWidget {parent}
|
||||
, configuration_ {configuration}
|
||||
, network_manager_ {network_manager}
|
||||
, http_only_ {false}
|
||||
, root_dir_ {configuration_->save_directory ()}
|
||||
, contents_ {this
|
||||
, network_manager_
|
||||
, QDir {root_dir_.absoluteFilePath (samples_dir_name)}.absoluteFilePath (contents_file_name)}
|
||||
{
|
||||
dir_icon_.addPixmap (style ()->standardPixmap (QStyle::SP_DirClosedIcon), QIcon::Normal, QIcon::Off);
|
||||
dir_icon_.addPixmap (style ()->standardPixmap (QStyle::SP_DirOpenIcon), QIcon::Normal, QIcon::On);
|
||||
file_icon_.addPixmap (style ()->standardPixmap (QStyle::SP_FileIcon));
|
||||
|
||||
setColumnCount (2);
|
||||
setHeaderLabels ({"File", "Progress"});
|
||||
header ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||
setItemDelegate (&item_delegate_);
|
||||
|
||||
connect (network_manager_, &QNetworkAccessManager::authenticationRequired
|
||||
, this, &Directory::authentication);
|
||||
connect (this, &Directory::itemChanged, [this] (QTreeWidgetItem * item) {
|
||||
switch (item->type ())
|
||||
{
|
||||
case FileNode::Type:
|
||||
{
|
||||
FileNode * node = static_cast<FileNode *> (item);
|
||||
if (!node->sync (node->checkState (0) == Qt::Checked))
|
||||
{
|
||||
FileNode::sync_blocker b {node};
|
||||
node->setCheckState (0, node->checkState (0) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool Directory::url_root (QUrl root)
|
||||
{
|
||||
if (!root.path ().endsWith ('/'))
|
||||
{
|
||||
root.setPath (root.path () + '/');
|
||||
}
|
||||
bool valid = root.isValid ();
|
||||
if (valid)
|
||||
{
|
||||
url_root_ = root;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
void Directory::error (QString const& title, QString const& message)
|
||||
{
|
||||
MessageBox::warning_message (this, title, message);
|
||||
}
|
||||
|
||||
bool Directory::refresh (bool http_only)
|
||||
{
|
||||
abort ();
|
||||
clear ();
|
||||
// update locations
|
||||
root_dir_ = configuration_->save_directory ();
|
||||
QDir contents_dir {root_dir_.absoluteFilePath (samples_dir_name)};
|
||||
contents_.local_file_path (contents_dir.absoluteFilePath (contents_file_name));
|
||||
contents_.http_only (http_only_ = http_only);
|
||||
QUrl url {url_root_.resolved (QDir {root_dir_.relativeFilePath (samples_dir_name)}.filePath (contents_file_name))};
|
||||
if (url.isValid ())
|
||||
{
|
||||
return contents_.sync (url, true, true); // attempt to fetch contents
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this
|
||||
, tr ("URL Error")
|
||||
, tr ("Invalid URL:\n\"%1\"")
|
||||
.arg (url.toDisplayString ()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Directory::download_finished (bool success)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
QFile contents {contents_.local_file_path ()};
|
||||
if (contents.open (QFile::ReadOnly | QFile::Text))
|
||||
{
|
||||
QJsonParseError json_status;
|
||||
auto content = QJsonDocument::fromJson (contents.readAll (), &json_status);
|
||||
if (json_status.error)
|
||||
{
|
||||
MessageBox::warning_message (this
|
||||
, tr ("JSON Error")
|
||||
, tr ("Contents file syntax error %1 at character offset %2")
|
||||
.arg (json_status.errorString ()).arg (json_status.offset));
|
||||
return;
|
||||
}
|
||||
if (!content.isArray ())
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("JSON Error")
|
||||
, tr ("Contents file top level must be a JSON array"));
|
||||
return;
|
||||
}
|
||||
QTreeWidgetItem * parent {invisibleRootItem ()};
|
||||
parent = new DirectoryNode {parent, samples_dir_name};
|
||||
parent->setIcon (0, dir_icon_);
|
||||
parent->setExpanded (true);
|
||||
parse_entries (content.array (), root_dir_.relativeFilePath (samples_dir_name), parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("File System Error")
|
||||
, tr ("Failed to open \"%1\"\nError: %2 - %3")
|
||||
.arg (contents.fileName ())
|
||||
.arg (contents.error ())
|
||||
.arg (contents.errorString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Directory::parse_entries (QJsonArray const& entries, QDir const& dir, QTreeWidgetItem * parent)
|
||||
{
|
||||
if (dir.isRelative () && !dir.path ().startsWith ('.'))
|
||||
{
|
||||
for (auto const& value: entries)
|
||||
{
|
||||
if (value.isObject ())
|
||||
{
|
||||
auto const& entry = value.toObject ();
|
||||
auto const& name = entry["name"].toString ();
|
||||
if (name.size () && !name.contains (QRegularExpression {R"([/:;])"}))
|
||||
{
|
||||
auto const& type = entry["type"].toString ();
|
||||
if ("file" == type)
|
||||
{
|
||||
QUrl url {url_root_.resolved (dir.filePath (name))};
|
||||
if (url.isValid ())
|
||||
{
|
||||
auto node = new FileNode {parent, network_manager_
|
||||
, QDir {root_dir_.filePath (dir.path ())}.absoluteFilePath (name)
|
||||
, url, http_only_};
|
||||
FileNode::sync_blocker b {node};
|
||||
node->setIcon (0, file_icon_);
|
||||
node->setCheckState (0, node->local () ? Qt::Checked : Qt::Unchecked);
|
||||
update (parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this
|
||||
, tr ("URL Error")
|
||||
, tr ("Invalid URL:\n\"%1\"")
|
||||
.arg (url.toDisplayString ()));
|
||||
}
|
||||
}
|
||||
else if ("directory" == type)
|
||||
{
|
||||
auto node = new DirectoryNode {parent, name};
|
||||
node->setIcon (0, dir_icon_);
|
||||
auto const& entries = entry["entries"];
|
||||
if (entries.isArray ())
|
||||
{
|
||||
parse_entries (entries.toArray ()
|
||||
, QDir {root_dir_.relativeFilePath (dir.path ())}.filePath (name)
|
||||
, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("JSON Error")
|
||||
, tr ("Contents entries must be a JSON array"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("JSON Error")
|
||||
, tr ("Contents entries must have a valid type"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("JSON Error")
|
||||
, tr ("Contents entries must have a valid name"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("JSON Error")
|
||||
, tr ("Contents entries must be JSON objects"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("JSON Error")
|
||||
, tr ("Contents directories must be relative and within \"%1\"")
|
||||
.arg (samples_dir_name));
|
||||
}
|
||||
}
|
||||
|
||||
void Directory::abort ()
|
||||
{
|
||||
QTreeWidgetItemIterator iter {this};
|
||||
while (*iter)
|
||||
{
|
||||
if ((*iter)->type () == FileNode::Type)
|
||||
{
|
||||
auto * node = static_cast<FileNode *> (*iter);
|
||||
node->abort ();
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
//
|
||||
// traverse the passed subtree accumulating the number of items, the
|
||||
// number we have size data for, the bytes downloaded so far and the
|
||||
// maximum bytes to expect
|
||||
//
|
||||
int recurse_children (QTreeWidgetItem const * item, int * counted
|
||||
, qint64 * bytes, qint64 * max)
|
||||
{
|
||||
int items {0};
|
||||
for (int index {0}; index < item->childCount (); ++index)
|
||||
{
|
||||
auto const * child = item->child (index);
|
||||
if (child->type () == FileNode::Type) // only count files
|
||||
{
|
||||
++items;
|
||||
if (auto size = child->data (1, Qt::UserRole).toLongLong ())
|
||||
{
|
||||
*max += size;
|
||||
++*counted;
|
||||
}
|
||||
*bytes += child->data (1, Qt::DisplayRole).toLongLong ();
|
||||
}
|
||||
else
|
||||
{
|
||||
// recurse into sub-directory subtrees
|
||||
items += recurse_children (child, counted, bytes, max);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
void Directory::update (QTreeWidgetItem * item)
|
||||
{
|
||||
// iterate the tree under item and accumulate the progress
|
||||
if (item)
|
||||
{
|
||||
Q_ASSERT (item->type () == DirectoryNode::Type);
|
||||
qint64 max {0};
|
||||
qint64 bytes {0};
|
||||
int counted {0};
|
||||
|
||||
// get the count, progress and size of children
|
||||
int items {recurse_children (item, &counted, &bytes, &max)};
|
||||
|
||||
// estimate size of items not yet downloaded as average of
|
||||
// those actually present
|
||||
if (counted)
|
||||
{
|
||||
max += (items - counted) * max / counted;
|
||||
}
|
||||
|
||||
// save as our progress
|
||||
item->setData (1, Qt::UserRole, max);
|
||||
item->setData (1, Qt::DisplayRole, bytes);
|
||||
|
||||
// recurse up to top
|
||||
update (item->parent ());
|
||||
}
|
||||
}
|
||||
|
||||
void Directory::authentication (QNetworkReply * /* reply */
|
||||
, QAuthenticator * /* authenticator */)
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("Network Error"), tr ("Authentication required"));
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef SAMPLE_DOWNLOADER_DIRECTORY_HPP__
|
||||
#define SAMPLE_DOWNLOADER_DIRECTORY_HPP__
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QTreeWidget>
|
||||
#include <QIcon>
|
||||
#include <QSize>
|
||||
#include <QDir>
|
||||
#include <QUrl>
|
||||
|
||||
#include "DirectoryDelegate.hpp"
|
||||
#include "RemoteFile.hpp"
|
||||
|
||||
class Configuration;
|
||||
class QNetworkAccessManager;
|
||||
class QTreeWidgetItem;
|
||||
class QNetworkReply;
|
||||
class QAuthenticator;
|
||||
class QJsonArray;
|
||||
|
||||
class Directory final
|
||||
: public QTreeWidget
|
||||
, protected RemoteFile::ListenerInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Directory (Configuration const * configuration
|
||||
, QNetworkAccessManager * network_manager
|
||||
, QWidget * parent = nullptr);
|
||||
|
||||
QSize sizeHint () const override {return {400, 500};}
|
||||
|
||||
bool url_root (QUrl);
|
||||
bool refresh (bool http_only);
|
||||
void abort ();
|
||||
void update (QTreeWidgetItem * item);
|
||||
|
||||
protected:
|
||||
void error (QString const& title, QString const& message) override;
|
||||
bool redirect_request (QUrl const&) override {return true;} // allow
|
||||
void download_finished (bool success) override;
|
||||
|
||||
private:
|
||||
Q_SLOT void authentication (QNetworkReply *, QAuthenticator *);
|
||||
void parse_entries (QJsonArray const& entries, QDir const& dir, QTreeWidgetItem * parent);
|
||||
|
||||
Configuration const * configuration_;
|
||||
QNetworkAccessManager * network_manager_;
|
||||
bool http_only_;
|
||||
QDir root_dir_;
|
||||
QUrl url_root_;
|
||||
RemoteFile contents_;
|
||||
DirectoryDelegate item_delegate_;
|
||||
QIcon dir_icon_;
|
||||
QIcon file_icon_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
#include "DirectoryDelegate.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
#include <QStyle>
|
||||
#include <QModelIndex>
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionViewItem>
|
||||
#include <QStyleOptionProgressBar>
|
||||
|
||||
void DirectoryDelegate::paint (QPainter * painter, QStyleOptionViewItem const& option
|
||||
, QModelIndex const& index) const
|
||||
{
|
||||
if (1 == index.column ())
|
||||
{
|
||||
QStyleOptionProgressBar progress_bar_option;
|
||||
progress_bar_option.rect = option.rect;
|
||||
progress_bar_option.state = QStyle::State_Enabled;
|
||||
progress_bar_option.direction = QApplication::layoutDirection ();
|
||||
progress_bar_option.fontMetrics = QApplication::fontMetrics ();
|
||||
progress_bar_option.minimum = 0;
|
||||
progress_bar_option.maximum = 100;
|
||||
auto progress = index.data ().toLongLong ();
|
||||
if (progress > 0)
|
||||
{
|
||||
auto percent = int (progress * 100 / index.data (Qt::UserRole).toLongLong ());
|
||||
progress_bar_option.progress = percent;
|
||||
progress_bar_option.text = QString::number (percent) + '%';
|
||||
progress_bar_option.textVisible = true;
|
||||
progress_bar_option.textAlignment = Qt::AlignCenter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not started
|
||||
progress_bar_option.progress = -1;
|
||||
}
|
||||
QApplication::style ()->drawControl (QStyle::CE_ProgressBar, &progress_bar_option, painter);
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyledItemDelegate::paint (painter, option, index);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#ifndef DIRECTORY_DELEGATE_HPP__
|
||||
#define DIRECTORY_DELEGATE_HPP__
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
class QObject;
|
||||
class QStyleOptionVoew;
|
||||
class QModelIndex;
|
||||
class QPainter;
|
||||
|
||||
//
|
||||
// Styled item delegate that renders a progress bar in column #1
|
||||
//
|
||||
// model column #1 DisplayRole is the progress in bytes
|
||||
// model column #1 UserRole is the expected number of bytes
|
||||
//
|
||||
class DirectoryDelegate final
|
||||
: public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit DirectoryDelegate (QObject * parent = nullptr)
|
||||
: QStyledItemDelegate {parent}
|
||||
{
|
||||
}
|
||||
|
||||
void paint (QPainter * painter, QStyleOptionViewItem const& option
|
||||
, QModelIndex const& index) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,51 +0,0 @@
|
||||
#ifndef DIRECTORY_NODE_HPP__
|
||||
#define DIRECTORY_NODE_HPP__
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QString>
|
||||
|
||||
//
|
||||
// Tree widget item representing a file system directory.
|
||||
//
|
||||
// It renders the directory name in the first column and progress
|
||||
// information in the 2nd column. The progress information consists of
|
||||
// two 64 bit integer values, the 1st in the DisplayRole is the number
|
||||
// of bytes received and the 2nd in the UserRole the total bytes
|
||||
// expected. The progress information is not automatically
|
||||
// maintained, see the Directory class for an example of how to
|
||||
// dynamically maintain the DirectoryNode progress values. The 1st
|
||||
// column also renders a tristate check box that controls the first
|
||||
// column check boxes of child items.
|
||||
//
|
||||
class DirectoryNode final
|
||||
: public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
explicit DirectoryNode (QTreeWidgetItem * parent, QString const& name)
|
||||
: QTreeWidgetItem {parent, Type}
|
||||
{
|
||||
setFlags (flags () | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
|
||||
setText (0, name);
|
||||
setCheckState (0, Qt::Unchecked);
|
||||
|
||||
// initialize as empty, the owning QTreeWidget must maintain these
|
||||
// progress values
|
||||
setData (1, Qt::DisplayRole, 0ll); // progress in bytes
|
||||
setData (1, Qt::UserRole, 0ll); // expected bytes
|
||||
}
|
||||
|
||||
bool operator == (QString const& name) const
|
||||
{
|
||||
return name == text (0);
|
||||
}
|
||||
|
||||
static int constexpr Type {UserType};
|
||||
};
|
||||
|
||||
inline
|
||||
bool operator == (QString const& lhs, DirectoryNode const& rhs)
|
||||
{
|
||||
return rhs == lhs;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,74 +0,0 @@
|
||||
#include "FileNode.hpp"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QUrl>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "Directory.hpp"
|
||||
#include "MessageBox.hpp"
|
||||
|
||||
FileNode::FileNode (QTreeWidgetItem * parent
|
||||
, QNetworkAccessManager * network_manager
|
||||
, QString const& local_file_path
|
||||
, QUrl const& url
|
||||
, bool http_only)
|
||||
: QTreeWidgetItem {parent, Type}
|
||||
, remote_file_ {this, network_manager, local_file_path, http_only}
|
||||
, block_sync_ {false}
|
||||
{
|
||||
sync_blocker b {this};
|
||||
setFlags (flags () | Qt::ItemIsUserCheckable);
|
||||
setText (0, QFileInfo {local_file_path}.fileName ()); // display
|
||||
setData (0, Qt::UserRole, url);
|
||||
setData (0, Qt::UserRole + 1, local_file_path); // local absolute path
|
||||
setCheckState (0, Qt::Unchecked);
|
||||
}
|
||||
|
||||
void FileNode::error (QString const& title, QString const& message)
|
||||
{
|
||||
MessageBox::warning_message (treeWidget (), title, message);
|
||||
}
|
||||
|
||||
bool FileNode::sync (bool local)
|
||||
{
|
||||
if (block_sync_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return remote_file_.sync (data (0, Qt::UserRole).toUrl (), local);
|
||||
}
|
||||
|
||||
void FileNode::download_progress (qint64 bytes_received, qint64 total_bytes)
|
||||
{
|
||||
sync_blocker b {this};
|
||||
setData (1, Qt::UserRole, total_bytes);
|
||||
if (bytes_received < 0)
|
||||
{
|
||||
setData (1, Qt::DisplayRole, 0ll);
|
||||
setCheckState (0, Qt::Unchecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
setData (1, Qt::DisplayRole, bytes_received);
|
||||
}
|
||||
static_cast<Directory *> (treeWidget ())->update (parent ());
|
||||
}
|
||||
|
||||
void FileNode::download_finished (bool success)
|
||||
{
|
||||
sync_blocker b {this};
|
||||
if (!success)
|
||||
{
|
||||
setData (1, Qt::UserRole, 0ll);
|
||||
setData (1, Qt::DisplayRole, 0ll);
|
||||
}
|
||||
setCheckState (0, success ? Qt::Checked : Qt::Unchecked);
|
||||
static_cast<Directory *> (treeWidget ())->update (parent ());
|
||||
}
|
||||
|
||||
void FileNode::abort ()
|
||||
{
|
||||
sync_blocker b {this};
|
||||
remote_file_.abort ();
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
#ifndef FILE_NODE_HPP__
|
||||
#define FILE_NODE_HPP__
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include "RemoteFile.hpp"
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QString;
|
||||
class QUrl;
|
||||
|
||||
//
|
||||
// A holder for a RemoteFile object linked to a QTreeWidget row.
|
||||
//
|
||||
// It renders the file name in first column and holds download
|
||||
// progress data in the second column. The progress information is a
|
||||
// 64 bit integer number of bytes in the DisplayRole and a total bytes
|
||||
// expected in the UserRole. The first column also renders a check box
|
||||
// that downloads the file when checked and removes the downloaded
|
||||
// file when unchecked. The URL and local absolute file path are
|
||||
// stored in the UserData and UserData+1 roles of the first column.
|
||||
//
|
||||
class FileNode final
|
||||
: public QTreeWidgetItem
|
||||
, protected RemoteFile::ListenerInterface
|
||||
{
|
||||
public:
|
||||
explicit FileNode (QTreeWidgetItem * parent
|
||||
, QNetworkAccessManager * network_manager
|
||||
, QString const& local_path
|
||||
, QUrl const& url
|
||||
, bool http_only);
|
||||
|
||||
bool local () const {return remote_file_.local ();}
|
||||
bool sync (bool local);
|
||||
void abort ();
|
||||
|
||||
static int constexpr Type {UserType + 1};
|
||||
|
||||
//
|
||||
// Clients may use this RAII class to block nested calls to sync
|
||||
// which may be troublesome, e.g. when UI updates cause recursion.
|
||||
//
|
||||
struct sync_blocker
|
||||
{
|
||||
sync_blocker (FileNode * node) : node_ {node} {node_->block_sync_ = true;}
|
||||
sync_blocker (sync_blocker const&) = delete;
|
||||
sync_blocker& operator = (sync_blocker const&) = delete;
|
||||
~sync_blocker () {node_->block_sync_ = false;}
|
||||
private:
|
||||
FileNode * node_;
|
||||
};
|
||||
|
||||
protected:
|
||||
void error (QString const& title, QString const& message) override;
|
||||
bool redirect_request (QUrl const&) override {return true;} // allow
|
||||
void download_progress (qint64 bytes_received, qint64 total_bytes) override;
|
||||
void download_finished (bool success) override;
|
||||
|
||||
private:
|
||||
RemoteFile remote_file_; // active download
|
||||
bool block_sync_;
|
||||
|
||||
friend struct sync_blocker;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
A UI for downloading sample files from a web server.
|
||||
|
||||
Works in concert with samples/CMakeLists.txt which generates the JSON
|
||||
contents description file and has a build target upload-samples that
|
||||
uploads the samples and content file to the project files server.
|
||||
@@ -1,271 +0,0 @@
|
||||
#include "RemoteFile.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QDir>
|
||||
#include <QByteArray>
|
||||
|
||||
#include "moc_RemoteFile.cpp"
|
||||
|
||||
RemoteFile::RemoteFile (ListenerInterface * listener, QNetworkAccessManager * network_manager
|
||||
, QString const& local_file_path, bool http_only, QObject * parent)
|
||||
: QObject {parent}
|
||||
, listener_ {listener}
|
||||
, network_manager_ {network_manager}
|
||||
, local_file_ {local_file_path}
|
||||
, http_only_ {http_only}
|
||||
, is_valid_ {false}
|
||||
, redirect_count_ {0}
|
||||
, file_ {local_file_path}
|
||||
{
|
||||
local_file_.setCaching (false);
|
||||
}
|
||||
|
||||
void RemoteFile::local_file_path (QString const& name)
|
||||
{
|
||||
QFileInfo new_file {name};
|
||||
new_file.setCaching (false);
|
||||
if (new_file != local_file_)
|
||||
{
|
||||
if (local_file_.exists ())
|
||||
{
|
||||
QFile file {local_file_.absoluteFilePath ()};
|
||||
if (!file.rename (new_file.absoluteFilePath ()))
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot rename file:\n\"%1\"\nto: \"%2\"\nError(%3): %4")
|
||||
.arg (file.fileName ())
|
||||
.arg (new_file.absoluteFilePath ())
|
||||
.arg (file.error ())
|
||||
.arg (file.errorString ()));
|
||||
}
|
||||
}
|
||||
std::swap (local_file_, new_file);
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteFile::local () const
|
||||
{
|
||||
auto is_local = (reply_ && !reply_->isFinished ()) || local_file_.exists ();
|
||||
if (is_local)
|
||||
{
|
||||
auto size = local_file_.size ();
|
||||
listener_->download_progress (size, size);
|
||||
listener_->download_finished (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_progress (-1, 0);
|
||||
}
|
||||
return is_local;
|
||||
}
|
||||
|
||||
bool RemoteFile::sync (QUrl const& url, bool local, bool force)
|
||||
{
|
||||
if (local)
|
||||
{
|
||||
if (!reply_ || reply_->isFinished ()) // not active download
|
||||
{
|
||||
if (force || !local_file_.exists () || url != url_)
|
||||
{
|
||||
url_ = url;
|
||||
redirect_count_ = 0;
|
||||
Q_ASSERT (!is_valid_);
|
||||
download (url_);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reply_ && reply_->isRunning ())
|
||||
{
|
||||
reply_->abort ();
|
||||
}
|
||||
if (local_file_.exists ())
|
||||
{
|
||||
auto path = local_file_.absoluteDir ();
|
||||
if (path.remove (local_file_.fileName ()))
|
||||
{
|
||||
listener_->download_progress (-1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot delete file:\n\"%1\"")
|
||||
.arg (local_file_.absoluteFilePath ()));
|
||||
return false;
|
||||
}
|
||||
path.rmpath (".");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteFile::download (QUrl url)
|
||||
{
|
||||
if (QNetworkAccessManager::Accessible != network_manager_->networkAccessible ()) {
|
||||
// try and recover network access for QNAM
|
||||
network_manager_->setNetworkAccessible (QNetworkAccessManager::Accessible);
|
||||
}
|
||||
|
||||
if (url.isValid () && (!QSslSocket::supportsSsl () || http_only_))
|
||||
{
|
||||
url.setScheme ("http");
|
||||
}
|
||||
QNetworkRequest request {url};
|
||||
request.setRawHeader ("User-Agent", "WSJT Sample Downloader");
|
||||
request.setOriginatingObject (this);
|
||||
|
||||
// this blocks for a second or two the first time it is used on
|
||||
// Windows - annoying
|
||||
if (!is_valid_)
|
||||
{
|
||||
reply_ = network_manager_->head (request);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_ = network_manager_->get (request);
|
||||
}
|
||||
|
||||
connect (reply_.data (), &QNetworkReply::finished, this, &RemoteFile::reply_finished);
|
||||
connect (reply_.data (), &QNetworkReply::readyRead, this, &RemoteFile::store);
|
||||
connect (reply_.data (), &QNetworkReply::downloadProgress
|
||||
, [this] (qint64 bytes_received, qint64 total_bytes) {
|
||||
// report progress of wanted file
|
||||
if (is_valid_)
|
||||
{
|
||||
listener_->download_progress (bytes_received, total_bytes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void RemoteFile::abort ()
|
||||
{
|
||||
if (reply_ && reply_->isRunning ())
|
||||
{
|
||||
reply_->abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteFile::reply_finished ()
|
||||
{
|
||||
if (!reply_) return; // we probably deleted it in an
|
||||
// earlier call
|
||||
QUrl redirect_url {reply_->attribute (QNetworkRequest::RedirectionTargetAttribute).toUrl ()};
|
||||
if (reply_->error () == QNetworkReply::NoError && !redirect_url.isEmpty ())
|
||||
{
|
||||
if (listener_->redirect_request (redirect_url))
|
||||
{
|
||||
if (++redirect_count_ < 10) // maintain sanity
|
||||
{
|
||||
// follow redirect
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
listener_->error (tr ("Network Error")
|
||||
, tr ("Too many redirects: %1")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_finished (false);
|
||||
listener_->error (tr ("Network Error")
|
||||
, tr ("Redirect not followed: %1")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
}
|
||||
else if (reply_->error () != QNetworkReply::NoError)
|
||||
{
|
||||
file_.cancelWriting ();
|
||||
file_.commit ();
|
||||
listener_->download_finished (false);
|
||||
is_valid_ = false; // reset
|
||||
// report errors that are not due to abort
|
||||
if (QNetworkReply::OperationCanceledError != reply_->error ())
|
||||
{
|
||||
listener_->error (tr ("Network Error"), reply_->errorString ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto path = QFileInfo {file_.fileName ()}.absoluteDir ();
|
||||
if (is_valid_ && !file_.commit ())
|
||||
{
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot commit changes to:\n\"%1\"")
|
||||
.arg (file_.fileName ()));
|
||||
path.rmpath ("."); // tidy empty directories
|
||||
listener_->download_finished (false);
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_valid_)
|
||||
{
|
||||
// now get the body content
|
||||
is_valid_ = true;
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
listener_->download_finished (true);
|
||||
is_valid_ = false; // reset
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reply_ && reply_->isFinished ())
|
||||
{
|
||||
reply_->deleteLater ();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteFile::store ()
|
||||
{
|
||||
if (is_valid_)
|
||||
{
|
||||
if (!file_.isOpen ())
|
||||
{
|
||||
// create temporary file in the final location
|
||||
auto path = QFileInfo {file_.fileName ()}.absoluteDir ();
|
||||
if (path.mkpath ("."))
|
||||
{
|
||||
if (!file_.open (QSaveFile::WriteOnly))
|
||||
{
|
||||
abort ();
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot open file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (path.path ())
|
||||
.arg (file_.error ())
|
||||
.arg (file_.errorString ()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
abort ();
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot make path:\n\"%1\"")
|
||||
.arg (path.path ()));
|
||||
}
|
||||
}
|
||||
if (file_.write (reply_->read (reply_->bytesAvailable ())) < 0)
|
||||
{
|
||||
abort ();
|
||||
listener_->error (tr ("File System Error")
|
||||
, tr ("Cannot write to file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (file_.fileName ())
|
||||
.arg (file_.error ())
|
||||
.arg (file_.errorString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
#ifndef REMOTE_FILE_HPP__
|
||||
#define REMOTE_FILE_HPP__
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include <QFileInfo>
|
||||
#include <QSaveFile>
|
||||
#include <QPointer>
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
|
||||
//
|
||||
// Synchronize an individual file specified by a URL to the local file
|
||||
// system
|
||||
//
|
||||
class RemoteFile final
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//
|
||||
// Clients of RemoteFile must provide an instance of this
|
||||
// interface. It may be used to receive information and requests
|
||||
// from the RemoteFile instance as it does its work.
|
||||
//
|
||||
class ListenerInterface
|
||||
{
|
||||
protected:
|
||||
ListenerInterface () {}
|
||||
|
||||
public:
|
||||
virtual void error (QString const& title, QString const& message) = 0;
|
||||
virtual bool redirect_request (QUrl const&) {return false;} // disallow
|
||||
virtual void download_progress (qint64 /* bytes_received */, qint64 /* total_bytes */) {}
|
||||
virtual void download_finished (bool /* success */) {}
|
||||
};
|
||||
|
||||
explicit RemoteFile (ListenerInterface * listener, QNetworkAccessManager * network_manager
|
||||
, QString const& local_file_path, bool http_only = false
|
||||
, QObject * parent = nullptr);
|
||||
|
||||
// true if local file exists or will do very soon
|
||||
bool local () const;
|
||||
|
||||
// download/remove the local file
|
||||
bool sync (QUrl const& url, bool local = true, bool force = false);
|
||||
|
||||
// abort an active download
|
||||
void abort ();
|
||||
|
||||
// change the local location, this will rename if the file exists locally
|
||||
void local_file_path (QString const&);
|
||||
|
||||
QString local_file_path () const {return local_file_.absoluteFilePath ();}
|
||||
QUrl url () const {return url_;}
|
||||
|
||||
// always use an http scheme for remote URLs
|
||||
void http_only (bool flag = true) {http_only_ = flag;}
|
||||
|
||||
private:
|
||||
void download (QUrl url);
|
||||
void reply_finished ();
|
||||
|
||||
Q_SLOT void store ();
|
||||
|
||||
Q_SIGNAL void redirect (QUrl const&, unsigned redirect_count);
|
||||
Q_SIGNAL void downloadProgress (qint64 bytes_received, qint64 total_bytes);
|
||||
Q_SIGNAL void finished ();
|
||||
|
||||
ListenerInterface * listener_;
|
||||
QNetworkAccessManager * network_manager_;
|
||||
QFileInfo local_file_;
|
||||
bool http_only_;
|
||||
QUrl url_;
|
||||
QPointer<QNetworkReply> reply_;
|
||||
bool is_valid_;
|
||||
unsigned redirect_count_;
|
||||
QSaveFile file_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <QDebug>
|
||||
#include <QDebugStateSaver>
|
||||
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "Radio.hpp"
|
||||
@@ -631,7 +633,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, DriftingDateTime::currentDateTimeUtc(), DriftingDateTime::currentDateTimeUtc(), QString {}});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
__ __ ______ _____ ________ __ __
|
||||
| \ _ | \ / \ | \| \ | \ | \
|
||||
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
|
||||
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
|
||||
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
|
||||
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
|
||||
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
|
||||
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
|
||||
Thanks to:
|
||||
|
||||
The FFTW library (http://www.fftw.org) without which the efficient
|
||||
generation of discrete fast Fourier transformations essential to the
|
||||
decoding DSP algorithms of WSJT-X would be a considerable part of the
|
||||
project.
|
||||
|
||||
The Qt project (http://qt-project.org) that allows us to deliver a
|
||||
rich industrial strength cross platform GUI application written in
|
||||
C++.
|
||||
|
||||
Nate Bargmann, N0NB, and the Hamlib developer team for their
|
||||
excellent library and for prompt review and acceptance of the many
|
||||
pull requests for upstream patches to Hamlib.
|
||||
|
||||
Dave Bernstein, AA6YQ, for being so receptive to suggestions
|
||||
allowing WSJT-X to cooperate with his excellent Amateur Radio DX and
|
||||
award chasing suite (http://www.dxlabsuite.com).
|
||||
|
||||
Laurie Cowcher, VK3AMA, for developing the partner applications
|
||||
JTAlertX and JTMacrosX (http://www.hamapps.com) that make DX chasing
|
||||
with WSJT-X such an efficient and pleasurable experience.
|
||||
|
||||
The CMake build and packaging tools (http://www.cmake.org) for
|
||||
their comprehensive scripting tools that make automation of building
|
||||
and packaging on all supported platforms possible.
|
||||
|
||||
The NSIS MS Windows installer scripting and generator tools
|
||||
(http://nsis.sourceforge.net) that, through the CPack NSIS generator,
|
||||
allows us to build a comprehensive Windows installer package.
|
||||
|
||||
The GNU Compiler Collection (http://gcc.gnu.org) that allows us to
|
||||
compile and link C++, Fortran and C code to the latest Standards and
|
||||
with high quality optimization.
|
||||
|
||||
The clang C++ & C compiler front ends and LLVM compiler back end
|
||||
tools (http://clang.llvm.org) that provide us with another, gcc
|
||||
compatible, high quality C++ and C compiler and Standard Library suite
|
||||
which, particularly on Apple Mac, allows our code to be ported to the
|
||||
maximum number of platforms.
|
||||
|
||||
The MinGW project (http://www.mingw.org) that ports the gcc
|
||||
compilers and related GNU tools to the MS Windows environment allowing
|
||||
a high quality C++, Fortran and C application to be portable between
|
||||
native MS Windows and other platforms such as Linux and Apple Mac.
|
||||
@@ -1,135 +0,0 @@
|
||||
#include "BeaconsModel.hpp"
|
||||
|
||||
#include <QStandardItem>
|
||||
#include <QFont>
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * const headings[] = {
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Client"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Time"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Snr"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "DT"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Frequency"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Drift"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Grid"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Power"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Live"),
|
||||
QT_TRANSLATE_NOOP ("BeaconsModel", "Callsign"),
|
||||
};
|
||||
|
||||
QString live_string (bool off_air)
|
||||
{
|
||||
return off_air ? QT_TRANSLATE_NOOP ("BeaconsModel", "no") : QT_TRANSLATE_NOOP ("BeaconsModel", "yes");
|
||||
}
|
||||
|
||||
QFont text_font {"Courier", 10};
|
||||
|
||||
QList<QStandardItem *> make_row (QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, Frequency frequency, qint32 drift, QString const& callsign
|
||||
, QString const& grid, qint32 power, bool off_air)
|
||||
{
|
||||
auto time_item = new QStandardItem {time.toString ("hh:mm")};
|
||||
time_item->setData (time);
|
||||
time_item->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto snr_item = new QStandardItem {QString::number (snr)};
|
||||
snr_item->setData (snr);
|
||||
snr_item->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto dt = new QStandardItem {QString::number (delta_time)};
|
||||
dt->setData (delta_time);
|
||||
dt->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto freq = new QStandardItem {Radio::pretty_frequency_MHz_string (frequency)};
|
||||
freq->setData (frequency);
|
||||
freq->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto dri = new QStandardItem {QString::number (drift)};
|
||||
dri->setData (drift);
|
||||
dri->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto gd = new QStandardItem {grid};
|
||||
gd->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto pwr = new QStandardItem {QString::number (power)};
|
||||
pwr->setData (power);
|
||||
pwr->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto live = new QStandardItem {live_string (off_air)};
|
||||
live->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
QList<QStandardItem *> row {
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, freq, dri, gd, pwr, live, new QStandardItem {callsign}};
|
||||
Q_FOREACH (auto& item, row)
|
||||
{
|
||||
item->setEditable (false);
|
||||
item->setFont (text_font);
|
||||
item->setTextAlignment (item->textAlignment () | Qt::AlignVCenter);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
BeaconsModel::BeaconsModel (QObject * parent)
|
||||
: QStandardItemModel {0, sizeof (headings) / sizeof (headings[0]), parent}
|
||||
{
|
||||
int column {0};
|
||||
for (auto const& heading : headings)
|
||||
{
|
||||
setHeaderData (column++, Qt::Horizontal, tr (heading));
|
||||
}
|
||||
}
|
||||
|
||||
void BeaconsModel::add_beacon_spot (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, Frequency frequency, qint32 drift, QString const& callsign
|
||||
, QString const& grid, qint32 power, bool off_air)
|
||||
{
|
||||
if (!is_new)
|
||||
{
|
||||
int target_row {-1};
|
||||
for (auto row = 0; row < rowCount (); ++row)
|
||||
{
|
||||
if (data (index (row, 0)).toString () == client_id)
|
||||
{
|
||||
auto row_time = item (row, 1)->data ().toTime ();
|
||||
if (row_time == time
|
||||
&& item (row, 2)->data ().toInt () == snr
|
||||
&& item (row, 3)->data ().toFloat () == delta_time
|
||||
&& item (row, 4)->data ().value<Frequency> () == frequency
|
||||
&& data (index (row, 5)).toInt () == drift
|
||||
&& data (index (row, 7)).toString () == grid
|
||||
&& data (index (row, 8)).toInt () == power
|
||||
&& data (index (row, 6)).toString () == live_string (off_air)
|
||||
&& data (index (row, 9)).toString () == callsign)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (time <= row_time)
|
||||
{
|
||||
target_row = row; // last row with same time
|
||||
}
|
||||
}
|
||||
}
|
||||
if (target_row >= 0)
|
||||
{
|
||||
insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power, off_air));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
appendRow (make_row (client_id, time, snr, delta_time, frequency, drift, callsign, grid, power, off_air));
|
||||
}
|
||||
|
||||
void BeaconsModel::clear_decodes (QString const& client_id)
|
||||
{
|
||||
for (auto row = rowCount () - 1; row >= 0; --row)
|
||||
{
|
||||
if (data (index (row, 0)).toString () == client_id)
|
||||
{
|
||||
removeRow (row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_BeaconsModel.cpp"
|
||||
@@ -1,38 +0,0 @@
|
||||
#ifndef WSJTX_UDP_BEACONS_MODEL_HPP__
|
||||
#define WSJTX_UDP_BEACONS_MODEL_HPP__
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include "MessageServer.hpp"
|
||||
|
||||
using Frequency = MessageServer::Frequency;
|
||||
|
||||
class QString;
|
||||
class QTime;
|
||||
|
||||
//
|
||||
// Beacons Model - simple data model for all beacon spots
|
||||
//
|
||||
// The model is a basic table with uniform row format. Rows consist of
|
||||
// QStandardItem instances containing the string representation of the
|
||||
// column data and if the underlying field is not a string then the
|
||||
// UserRole+1 role contains the underlying data item.
|
||||
//
|
||||
// Two slots are provided to add a new decode and remove all spots for
|
||||
// a client.
|
||||
//
|
||||
class BeaconsModel
|
||||
: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit BeaconsModel (QObject * parent = nullptr);
|
||||
|
||||
Q_SLOT void add_beacon_spot (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, Frequency frequency, qint32 drift, QString const& callsign, QString const& grid
|
||||
, qint32 power, bool off_air);
|
||||
Q_SLOT void clear_decodes (QString const& client_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,310 +0,0 @@
|
||||
#include "ClientWidget.hpp"
|
||||
|
||||
#include <QRegExp>
|
||||
#include <QColor>
|
||||
|
||||
#include "MaidenheadLocatorValidator.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
//QRegExp message_alphabet {"[- A-Za-z0-9+./?]*"};
|
||||
QRegExp message_alphabet {"[- @A-Za-z0-9+./?#<>]*"};
|
||||
QRegularExpression cq_re {"(CQ|CQDX|QRZ)[^A-Z0-9/]+"};
|
||||
|
||||
void update_dynamic_property (QWidget * widget, char const * property, QVariant const& value)
|
||||
{
|
||||
widget->setProperty (property, value);
|
||||
widget->style ()->unpolish (widget);
|
||||
widget->style ()->polish (widget);
|
||||
widget->update ();
|
||||
}
|
||||
}
|
||||
|
||||
ClientWidget::IdFilterModel::IdFilterModel (QString const& client_id)
|
||||
: client_id_ {client_id}
|
||||
, rx_df_ (-1)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant ClientWidget::IdFilterModel::data (QModelIndex const& proxy_index, int role) const
|
||||
{
|
||||
if (role == Qt::BackgroundRole)
|
||||
{
|
||||
switch (proxy_index.column ())
|
||||
{
|
||||
case 8: // message
|
||||
{
|
||||
auto message = QSortFilterProxyModel::data (proxy_index).toString ();
|
||||
if (base_call_re_.pattern ().size ()
|
||||
&& message.contains (base_call_re_))
|
||||
{
|
||||
return QColor {255,200,200};
|
||||
}
|
||||
if (message.contains (cq_re))
|
||||
{
|
||||
return QColor {200, 255, 200};
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // DF
|
||||
if (qAbs (QSortFilterProxyModel::data (proxy_index).toInt () - rx_df_) <= 10)
|
||||
{
|
||||
return QColor {255, 200, 200};
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QSortFilterProxyModel::data (proxy_index, role);
|
||||
}
|
||||
|
||||
bool ClientWidget::IdFilterModel::filterAcceptsRow (int source_row
|
||||
, QModelIndex const& source_parent) const
|
||||
{
|
||||
auto source_index_col0 = sourceModel ()->index (source_row, 0, source_parent);
|
||||
return sourceModel ()->data (source_index_col0).toString () == client_id_;
|
||||
}
|
||||
|
||||
void ClientWidget::IdFilterModel::de_call (QString const& call)
|
||||
{
|
||||
if (call != call_)
|
||||
{
|
||||
beginResetModel ();
|
||||
if (call.size ())
|
||||
{
|
||||
base_call_re_.setPattern ("[^A-Z0-9]*" + Radio::base_callsign (call) + "[^A-Z0-9]*");
|
||||
}
|
||||
else
|
||||
{
|
||||
base_call_re_.setPattern (QString {});
|
||||
}
|
||||
call_ = call;
|
||||
endResetModel ();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientWidget::IdFilterModel::rx_df (int df)
|
||||
{
|
||||
if (df != rx_df_)
|
||||
{
|
||||
beginResetModel ();
|
||||
rx_df_ = df;
|
||||
endResetModel ();
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
QString make_title (QString const& id, QString const& version, QString const& revision)
|
||||
{
|
||||
QString title {id};
|
||||
if (version.size ())
|
||||
{
|
||||
title += QString {" v%1"}.arg (version);
|
||||
}
|
||||
if (revision.size ())
|
||||
{
|
||||
title += QString {" (%1)"}.arg (revision);
|
||||
}
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemModel * beacons_model
|
||||
, QString const& id, QString const& version, QString const& revision
|
||||
, QListWidget const * calls_of_interest, QWidget * parent)
|
||||
: QDockWidget {make_title (id, version, revision), parent}
|
||||
, id_ {id}
|
||||
, calls_of_interest_ {calls_of_interest}
|
||||
, decodes_proxy_model_ {id_}
|
||||
, decodes_table_view_ {new QTableView}
|
||||
, beacons_table_view_ {new QTableView}
|
||||
, message_line_edit_ {new QLineEdit}
|
||||
, grid_line_edit_ {new QLineEdit}
|
||||
, decodes_stack_ {new QStackedLayout}
|
||||
, auto_off_button_ {new QPushButton {tr ("&Auto Off")}}
|
||||
, halt_tx_button_ {new QPushButton {tr ("&Halt Tx")}}
|
||||
, de_label_ {new QLabel}
|
||||
, mode_label_ {new QLabel}
|
||||
, fast_mode_ {false}
|
||||
, frequency_label_ {new QLabel}
|
||||
, dx_label_ {new QLabel}
|
||||
, rx_df_label_ {new QLabel}
|
||||
, tx_df_label_ {new QLabel}
|
||||
, report_label_ {new QLabel}
|
||||
, columns_resized_ {false}
|
||||
{
|
||||
// set up widgets
|
||||
decodes_proxy_model_.setSourceModel (decodes_model);
|
||||
decodes_table_view_->setModel (&decodes_proxy_model_);
|
||||
decodes_table_view_->verticalHeader ()->hide ();
|
||||
decodes_table_view_->hideColumn (0);
|
||||
decodes_table_view_->horizontalHeader ()->setStretchLastSection (true);
|
||||
|
||||
auto form_layout = new QFormLayout;
|
||||
form_layout->addRow (tr ("Free text:"), message_line_edit_);
|
||||
form_layout->addRow (tr ("Temporary grid:"), grid_line_edit_);
|
||||
message_line_edit_->setValidator (new QRegExpValidator {message_alphabet, this});
|
||||
grid_line_edit_->setValidator (new MaidenheadLocatorValidator {this});
|
||||
connect (message_line_edit_, &QLineEdit::textEdited, [this] (QString const& text) {
|
||||
Q_EMIT do_free_text (id_, text, false);
|
||||
});
|
||||
connect (message_line_edit_, &QLineEdit::editingFinished, [this] () {
|
||||
Q_EMIT do_free_text (id_, message_line_edit_->text (), true);
|
||||
});
|
||||
connect (grid_line_edit_, &QLineEdit::editingFinished, [this] () {
|
||||
Q_EMIT location (id_, grid_line_edit_->text ());
|
||||
});
|
||||
|
||||
auto decodes_page = new QWidget;
|
||||
auto decodes_layout = new QVBoxLayout {decodes_page};
|
||||
decodes_layout->setContentsMargins (QMargins {2, 2, 2, 2});
|
||||
decodes_layout->addWidget (decodes_table_view_);
|
||||
decodes_layout->addLayout (form_layout);
|
||||
|
||||
auto beacons_proxy_model = new IdFilterModel {id_};
|
||||
beacons_proxy_model->setSourceModel (beacons_model);
|
||||
beacons_table_view_->setModel (beacons_proxy_model);
|
||||
beacons_table_view_->verticalHeader ()->hide ();
|
||||
beacons_table_view_->hideColumn (0);
|
||||
beacons_table_view_->horizontalHeader ()->setStretchLastSection (true);
|
||||
|
||||
auto beacons_page = new QWidget;
|
||||
auto beacons_layout = new QVBoxLayout {beacons_page};
|
||||
beacons_layout->setContentsMargins (QMargins {2, 2, 2, 2});
|
||||
beacons_layout->addWidget (beacons_table_view_);
|
||||
|
||||
decodes_stack_->addWidget (decodes_page);
|
||||
decodes_stack_->addWidget (beacons_page);
|
||||
|
||||
// stack alternative views
|
||||
auto content_layout = new QVBoxLayout;
|
||||
content_layout->setContentsMargins (QMargins {2, 2, 2, 2});
|
||||
content_layout->addLayout (decodes_stack_);
|
||||
|
||||
// set up controls
|
||||
auto control_button_box = new QDialogButtonBox;
|
||||
control_button_box->addButton (auto_off_button_, QDialogButtonBox::ActionRole);
|
||||
control_button_box->addButton (halt_tx_button_, QDialogButtonBox::ActionRole);
|
||||
connect (auto_off_button_, &QAbstractButton::clicked, [this] (bool /* checked */) {
|
||||
Q_EMIT do_halt_tx (id_, true);
|
||||
});
|
||||
connect (halt_tx_button_, &QAbstractButton::clicked, [this] (bool /* checked */) {
|
||||
Q_EMIT do_halt_tx (id_, false);
|
||||
});
|
||||
content_layout->addWidget (control_button_box);
|
||||
|
||||
// set up status area
|
||||
auto status_bar = new QStatusBar;
|
||||
status_bar->addPermanentWidget (de_label_);
|
||||
status_bar->addPermanentWidget (mode_label_);
|
||||
status_bar->addPermanentWidget (frequency_label_);
|
||||
status_bar->addPermanentWidget (dx_label_);
|
||||
status_bar->addPermanentWidget (rx_df_label_);
|
||||
status_bar->addPermanentWidget (tx_df_label_);
|
||||
status_bar->addPermanentWidget (report_label_);
|
||||
content_layout->addWidget (status_bar);
|
||||
connect (this, &ClientWidget::topLevelChanged, status_bar, &QStatusBar::setSizeGripEnabled);
|
||||
|
||||
// set up central widget
|
||||
auto content_widget = new QFrame;
|
||||
content_widget->setFrameStyle (QFrame::StyledPanel | QFrame::Sunken);
|
||||
content_widget->setLayout (content_layout);
|
||||
setWidget (content_widget);
|
||||
// setMinimumSize (QSize {550, 0});
|
||||
setFeatures (DockWidgetMovable | DockWidgetFloatable);
|
||||
setAllowedAreas (Qt::BottomDockWidgetArea);
|
||||
setFloating (true);
|
||||
|
||||
// connect up table view signals
|
||||
connect (decodes_table_view_, &QTableView::doubleClicked, this, [this] (QModelIndex const& index) {
|
||||
Q_EMIT do_reply (decodes_proxy_model_.mapToSource (index), QApplication::keyboardModifiers () >> 24);
|
||||
});
|
||||
|
||||
// tell new client about calls of interest
|
||||
for (int row = 0; row < calls_of_interest_->count (); ++row)
|
||||
{
|
||||
Q_EMIT highlight_callsign (id_, calls_of_interest_->item (row)->text (), QColor {Qt::blue}, QColor {Qt::yellow});
|
||||
}
|
||||
}
|
||||
|
||||
ClientWidget::~ClientWidget ()
|
||||
{
|
||||
for (int row = 0; row < calls_of_interest_->count (); ++row)
|
||||
{
|
||||
// tell client to forget calls of interest
|
||||
Q_EMIT highlight_callsign (id_, calls_of_interest_->item (row)->text ());
|
||||
}
|
||||
}
|
||||
|
||||
void ClientWidget::update_status (QString const& id, 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 (id == id_)
|
||||
{
|
||||
fast_mode_ = fast_mode;
|
||||
decodes_proxy_model_.de_call (de_call);
|
||||
decodes_proxy_model_.rx_df (rx_df);
|
||||
de_label_->setText (de_call.size () >= 0 ? QString {"DE: %1%2"}.arg (de_call)
|
||||
.arg (de_grid.size () ? '(' + de_grid + ')' : QString {}) : QString {});
|
||||
mode_label_->setText (QString {"Mode: %1%2%3%4"}
|
||||
.arg (mode)
|
||||
.arg (sub_mode)
|
||||
.arg (fast_mode && !mode.contains (QRegularExpression {R"(ISCAT|MSK144)"}) ? "fast" : "")
|
||||
.arg (tx_mode.isEmpty () || tx_mode == mode ? "" : '(' + tx_mode + ')'));
|
||||
frequency_label_->setText ("QRG: " + Radio::pretty_frequency_MHz_string (f));
|
||||
dx_label_->setText (dx_call.size () >= 0 ? QString {"DX: %1%2"}.arg (dx_call)
|
||||
.arg (dx_grid.size () ? '(' + dx_grid + ')' : QString {}) : QString {});
|
||||
rx_df_label_->setText (rx_df >= 0 ? QString {"Rx: %1"}.arg (rx_df) : "");
|
||||
tx_df_label_->setText (tx_df >= 0 ? QString {"Tx: %1"}.arg (tx_df) : "");
|
||||
report_label_->setText ("SNR: " + report);
|
||||
update_dynamic_property (frequency_label_, "transmitting", transmitting);
|
||||
auto_off_button_->setEnabled (tx_enabled);
|
||||
halt_tx_button_->setEnabled (transmitting);
|
||||
update_dynamic_property (mode_label_, "decoding", decoding);
|
||||
update_dynamic_property (tx_df_label_, "watchdog_timeout", watchdog_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientWidget::decode_added (bool /*is_new*/, QString const& client_id, QTime /*time*/, qint32 /*snr*/
|
||||
, float /*delta_time*/, quint32 /*delta_frequency*/, QString const& /*mode*/
|
||||
, QString const& /*message*/, bool /*low_confidence*/, bool /*off_air*/)
|
||||
{
|
||||
if (client_id == id_ && !columns_resized_)
|
||||
{
|
||||
decodes_stack_->setCurrentIndex (0);
|
||||
decodes_table_view_->resizeColumnsToContents ();
|
||||
columns_resized_ = true;
|
||||
}
|
||||
decodes_table_view_->scrollToBottom ();
|
||||
}
|
||||
|
||||
void ClientWidget::beacon_spot_added (bool /*is_new*/, QString const& client_id, QTime /*time*/, qint32 /*snr*/
|
||||
, float /*delta_time*/, Frequency /*delta_frequency*/, qint32 /*drift*/
|
||||
, QString const& /*callsign*/, QString const& /*grid*/, qint32 /*power*/
|
||||
, bool /*off_air*/)
|
||||
{
|
||||
if (client_id == id_ && !columns_resized_)
|
||||
{
|
||||
decodes_stack_->setCurrentIndex (1);
|
||||
beacons_table_view_->resizeColumnsToContents ();
|
||||
columns_resized_ = true;
|
||||
}
|
||||
beacons_table_view_->scrollToBottom ();
|
||||
}
|
||||
|
||||
void ClientWidget::clear_decodes (QString const& client_id)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
columns_resized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_ClientWidget.cpp"
|
||||
@@ -1,94 +0,0 @@
|
||||
#ifndef WSJTX_UDP_CLIENT_WIDGET_MODEL_HPP__
|
||||
#define WSJTX_UDP_CLIENT_WIDGET_MODEL_HPP__
|
||||
|
||||
#include <QObject>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QString>
|
||||
#include <QRegularExpression>
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "MessageServer.hpp"
|
||||
|
||||
class QAbstractItemModel;
|
||||
class QModelIndex;
|
||||
class QColor;
|
||||
|
||||
using Frequency = MessageServer::Frequency;
|
||||
|
||||
class ClientWidget
|
||||
: public QDockWidget
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemModel * beacons_model
|
||||
, QString const& id, QString const& version, QString const& revision
|
||||
, QListWidget const * calls_of_interest, QWidget * parent = nullptr);
|
||||
~ClientWidget ();
|
||||
|
||||
bool fast_mode () const {return fast_mode_;}
|
||||
|
||||
Q_SLOT void update_status (QString const& id, 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);
|
||||
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence, bool off_air);
|
||||
Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
||||
, float delta_time, Frequency delta_frequency, qint32 drift
|
||||
, QString const& callsign, QString const& grid, qint32 power
|
||||
, bool off_air);
|
||||
Q_SLOT void clear_decodes (QString const& client_id);
|
||||
|
||||
Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier);
|
||||
Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only);
|
||||
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
|
||||
Q_SIGNAL void location (QString const& id, QString const& text);
|
||||
Q_SIGNAL void highlight_callsign (QString const& id, QString const& call
|
||||
, QColor const& bg = QColor {}, QColor const& fg = QColor {}
|
||||
, bool last_only = false);
|
||||
|
||||
private:
|
||||
QString id_;
|
||||
QListWidget const * calls_of_interest_;
|
||||
class IdFilterModel final
|
||||
: public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
IdFilterModel (QString const& client_id);
|
||||
|
||||
void de_call (QString const&);
|
||||
void rx_df (int);
|
||||
|
||||
QVariant data (QModelIndex const& proxy_index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow (int source_row, QModelIndex const& source_parent) const override;
|
||||
|
||||
private:
|
||||
QString client_id_;
|
||||
QString call_;
|
||||
QRegularExpression base_call_re_;
|
||||
int rx_df_;
|
||||
} decodes_proxy_model_;
|
||||
QTableView * decodes_table_view_;
|
||||
QTableView * beacons_table_view_;
|
||||
QLineEdit * message_line_edit_;
|
||||
QLineEdit * grid_line_edit_;
|
||||
QStackedLayout * decodes_stack_;
|
||||
QAbstractButton * auto_off_button_;
|
||||
QAbstractButton * halt_tx_button_;
|
||||
QLabel * de_label_;
|
||||
QLabel * mode_label_;
|
||||
bool fast_mode_;
|
||||
QLabel * frequency_label_;
|
||||
QLabel * dx_label_;
|
||||
QLabel * rx_df_label_;
|
||||
QLabel * tx_df_label_;
|
||||
QLabel * report_label_;
|
||||
bool columns_resized_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,153 +0,0 @@
|
||||
#include "DecodesModel.hpp"
|
||||
|
||||
#include <QStandardItem>
|
||||
#include <QModelIndex>
|
||||
#include <QTime>
|
||||
#include <QString>
|
||||
#include <QFont>
|
||||
#include <QList>
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * const headings[] = {
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Client"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Time"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Snr"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "DT"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "DF"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Md"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Confidence"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Live"),
|
||||
QT_TRANSLATE_NOOP ("DecodesModel", "Message"),
|
||||
};
|
||||
|
||||
QString confidence_string (bool low_confidence)
|
||||
{
|
||||
return low_confidence ? QT_TRANSLATE_NOOP ("DecodesModel", "low") : QT_TRANSLATE_NOOP ("DecodesModel", "high");
|
||||
}
|
||||
|
||||
QString live_string (bool off_air)
|
||||
{
|
||||
return off_air ? QT_TRANSLATE_NOOP ("DecodesModel", "no") : QT_TRANSLATE_NOOP ("DecodesModel", "yes");
|
||||
}
|
||||
|
||||
QFont text_font {"Courier", 10};
|
||||
|
||||
QList<QStandardItem *> make_row (QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence, bool off_air, bool is_fast)
|
||||
{
|
||||
auto time_item = new QStandardItem {time.toString (is_fast || "~" == mode ? "hh:mm:ss" : "hh:mm")};
|
||||
time_item->setData (time);
|
||||
time_item->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto snr_item = new QStandardItem {QString::number (snr)};
|
||||
snr_item->setData (snr);
|
||||
snr_item->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto dt = new QStandardItem {QString::number (delta_time)};
|
||||
dt->setData (delta_time);
|
||||
dt->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto df = new QStandardItem {QString::number (delta_frequency)};
|
||||
df->setData (delta_frequency);
|
||||
df->setTextAlignment (Qt::AlignRight);
|
||||
|
||||
auto md = new QStandardItem {mode};
|
||||
md->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
auto confidence = new QStandardItem {confidence_string (low_confidence)};
|
||||
confidence->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
auto live = new QStandardItem {live_string (off_air)};
|
||||
live->setTextAlignment (Qt::AlignHCenter);
|
||||
|
||||
QList<QStandardItem *> row {
|
||||
new QStandardItem {client_id}, time_item, snr_item, dt, df, md, confidence, live, new QStandardItem {message}};
|
||||
Q_FOREACH (auto& item, row)
|
||||
{
|
||||
item->setEditable (false);
|
||||
item->setFont (text_font);
|
||||
item->setTextAlignment (item->textAlignment () | Qt::AlignVCenter);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
DecodesModel::DecodesModel (QObject * parent)
|
||||
: QStandardItemModel {0, sizeof (headings) / sizeof (headings[0]), parent}
|
||||
{
|
||||
int column {0};
|
||||
for (auto const& heading : headings)
|
||||
{
|
||||
setHeaderData (column++, Qt::Horizontal, tr (heading));
|
||||
}
|
||||
}
|
||||
|
||||
void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence, bool off_air, bool is_fast)
|
||||
{
|
||||
if (!is_new)
|
||||
{
|
||||
int target_row {-1};
|
||||
for (auto row = 0; row < rowCount (); ++row)
|
||||
{
|
||||
if (data (index (row, 0)).toString () == client_id)
|
||||
{
|
||||
auto row_time = item (row, 1)->data ().toTime ();
|
||||
if (row_time == time
|
||||
&& item (row, 2)->data ().toInt () == snr
|
||||
&& item (row, 3)->data ().toFloat () == delta_time
|
||||
&& item (row, 4)->data ().toUInt () == delta_frequency
|
||||
&& data (index (row, 5)).toString () == mode
|
||||
&& data (index (row, 7)).toString () == confidence_string (low_confidence)
|
||||
&& data (index (row, 6)).toString () == live_string (off_air)
|
||||
&& data (index (row, 8)).toString () == message)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (time <= row_time)
|
||||
{
|
||||
target_row = row; // last row with same time
|
||||
}
|
||||
}
|
||||
}
|
||||
if (target_row >= 0)
|
||||
{
|
||||
insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, delta_frequency, mode
|
||||
, message, low_confidence, off_air, is_fast));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
appendRow (make_row (client_id, time, snr, delta_time, delta_frequency, mode, message, low_confidence
|
||||
, off_air, is_fast));
|
||||
}
|
||||
|
||||
void DecodesModel::clear_decodes (QString const& client_id)
|
||||
{
|
||||
for (auto row = rowCount () - 1; row >= 0; --row)
|
||||
{
|
||||
if (data (index (row, 0)).toString () == client_id)
|
||||
{
|
||||
removeRow (row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecodesModel::do_reply (QModelIndex const& source, quint8 modifiers)
|
||||
{
|
||||
auto row = source.row ();
|
||||
Q_EMIT reply (data (index (row, 0)).toString ()
|
||||
, item (row, 1)->data ().toTime ()
|
||||
, item (row, 2)->data ().toInt ()
|
||||
, item (row, 3)->data ().toFloat ()
|
||||
, item (row, 4)->data ().toInt ()
|
||||
, data (index (row, 5)).toString ()
|
||||
, data (index (row, 8)).toString ()
|
||||
, confidence_string (true) == data (index (row, 7)).toString ()
|
||||
, modifiers);
|
||||
}
|
||||
|
||||
#include "moc_DecodesModel.cpp"
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef WSJTX_UDP_DECODES_MODEL_HPP__
|
||||
#define WSJTX_UDP_DECODES_MODEL_HPP__
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include "MessageServer.hpp"
|
||||
|
||||
using Frequency = MessageServer::Frequency;
|
||||
|
||||
class QTime;
|
||||
class QString;
|
||||
class QModelIndex;
|
||||
|
||||
//
|
||||
// Decodes Model - simple data model for all decodes
|
||||
//
|
||||
// The model is a basic table with uniform row format. Rows consist of
|
||||
// QStandardItem instances containing the string representation of the
|
||||
// column data and if the underlying field is not a string then the
|
||||
// UserRole+1 role contains the underlying data item.
|
||||
//
|
||||
// Three slots are provided to add a new decode, remove all decodes
|
||||
// for a client and, to build a reply to CQ message for a given row
|
||||
// which is emitted as a signal respectively.
|
||||
//
|
||||
class DecodesModel
|
||||
: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit DecodesModel (QObject * parent = nullptr);
|
||||
|
||||
Q_SLOT void add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||
, bool low_confidence, bool off_air, bool is_fast);
|
||||
Q_SLOT void clear_decodes (QString const& client_id);
|
||||
Q_SLOT void do_reply (QModelIndex const& source, quint8 modifiers);
|
||||
|
||||
Q_SIGNAL void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||
, QString const& mode, QString const& message, bool low_confidence, quint8 modifiers);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,90 +0,0 @@
|
||||
//
|
||||
// MessageAggregator - an example application that utilizes the WSJT-X
|
||||
// messaging facility
|
||||
//
|
||||
// This application is only provided as a simple GUI application
|
||||
// example to demonstrate the WSJT-X messaging facility. It allows the
|
||||
// user to set the server details either as a unicast UDP server or,
|
||||
// if a multicast group address is provided, as a multicast server.
|
||||
// The benefit of the multicast server is that multiple servers can be
|
||||
// active at once each receiving all WSJT-X broadcast messages and
|
||||
// each able to respond to individual WSJT_X clients. To utilize the
|
||||
// multicast group features each WSJT-X client must set the same
|
||||
// multicast group address as the UDP server address for example
|
||||
// 239.255.0.0 for a site local multicast group.
|
||||
//
|
||||
// The UI is a small panel to input the service port number and
|
||||
// optionally the multicast group address. Below that a table
|
||||
// representing the log entries where any QSO logged messages
|
||||
// broadcast from WSJT-X clients are displayed. The bottom of the
|
||||
// application main window is a dock area where a dock window will
|
||||
// appear for each WSJT-X client, this window contains a table of the
|
||||
// current decode messages broadcast from that WSJT-X client and a
|
||||
// status line showing the status update messages broadcast from the
|
||||
// WSJT-X client. The dock windows may be arranged in a tab bar, side
|
||||
// by side, below each other or, completely detached from the dock
|
||||
// area as floating windows. Double clicking the dock window title bar
|
||||
// or dragging and dropping with the mouse allows these different
|
||||
// arrangements.
|
||||
//
|
||||
// The application also provides a simple menu bar including a view
|
||||
// menu that allows each dock window to be hidden or revealed.
|
||||
//
|
||||
|
||||
#include <clocale>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QObject>
|
||||
|
||||
#include "MessageAggregatorMainWindow.hpp"
|
||||
|
||||
// deduce the size of an array
|
||||
template<class T, size_t N>
|
||||
inline
|
||||
size_t size (T (&)[N]) {return N;}
|
||||
|
||||
int main (int argc, char * argv[])
|
||||
{
|
||||
QApplication app {argc, argv};
|
||||
try
|
||||
{
|
||||
setlocale (LC_NUMERIC, "C"); // ensure number forms are in
|
||||
// consistent format, do this after
|
||||
// instantiating QApplication so
|
||||
// that GUI has correct l18n
|
||||
|
||||
app.setApplicationName ("WSJT-X Reference UDP Message Aggregator Server");
|
||||
app.setApplicationVersion ("1.0");
|
||||
|
||||
QObject::connect (&app, SIGNAL (lastWindowClosed ()), &app, SLOT (quit ()));
|
||||
|
||||
{
|
||||
QFile file {":/qss/default.qss"};
|
||||
if (!file.open (QFile::ReadOnly))
|
||||
{
|
||||
throw std::runtime_error {
|
||||
QString {"failed to open \"" + file.fileName () + "\": " + file.errorString ()}
|
||||
.toLocal8Bit ().constData ()};
|
||||
}
|
||||
app.setStyleSheet (file.readAll());
|
||||
}
|
||||
|
||||
MessageAggregatorMainWindow window;
|
||||
return app.exec ();
|
||||
}
|
||||
catch (std::exception const & e)
|
||||
{
|
||||
QMessageBox::critical (nullptr, app.applicationName (), e.what ());
|
||||
std::cerr << "Error: " << e.what () << '\n';
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
QMessageBox::critical (nullptr, app.applicationName (), QObject::tr ("Unexpected error"));
|
||||
std::cerr << "Unexpected error\n";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
#include "MessageAggregatorMainWindow.hpp"
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "DecodesModel.hpp"
|
||||
#include "BeaconsModel.hpp"
|
||||
#include "ClientWidget.hpp"
|
||||
|
||||
using port_type = MessageServer::port_type;
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * const headings[] = {
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Time On"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Time Off"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Callsign"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Grid"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Name"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Frequency"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Mode"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Sent"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Rec'd"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Power"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Operator"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Call"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Grid"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Comments"),
|
||||
};
|
||||
}
|
||||
|
||||
MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
||||
: log_ {new QStandardItemModel {0, 14, this}}
|
||||
, decodes_model_ {new DecodesModel {this}}
|
||||
, beacons_model_ {new BeaconsModel {this}}
|
||||
, server_ {new MessageServer {this}}
|
||||
, multicast_group_line_edit_ {new QLineEdit}
|
||||
, log_table_view_ {new QTableView}
|
||||
, add_call_of_interest_action_ {new QAction {tr ("&Add callsign"), this}}
|
||||
, delete_call_of_interest_action_ {new QAction {tr ("&Delete callsign"), this}}
|
||||
, last_call_of_interest_action_ {new QAction {tr ("&Highlight last only"), this}}
|
||||
, call_of_interest_bg_colour_action_ {new QAction {tr ("&Background colour"), this}}
|
||||
, call_of_interest_fg_colour_action_ {new QAction {tr ("&Foreground colour"), this}}
|
||||
{
|
||||
// logbook
|
||||
int column {0};
|
||||
for (auto const& heading : headings)
|
||||
{
|
||||
log_->setHeaderData (column++, Qt::Horizontal, tr (heading));
|
||||
}
|
||||
connect (server_, &MessageServer::qso_logged, this, &MessageAggregatorMainWindow::log_qso);
|
||||
|
||||
// menu bar
|
||||
auto file_menu = menuBar ()->addMenu (tr ("&File"));
|
||||
|
||||
auto exit_action = new QAction {tr ("E&xit"), this};
|
||||
exit_action->setShortcuts (QKeySequence::Quit);
|
||||
exit_action->setToolTip (tr ("Exit the application"));
|
||||
file_menu->addAction (exit_action);
|
||||
connect (exit_action, &QAction::triggered, this, &MessageAggregatorMainWindow::close);
|
||||
|
||||
view_menu_ = menuBar ()->addMenu (tr ("&View"));
|
||||
|
||||
// central layout
|
||||
auto central_layout = new QVBoxLayout;
|
||||
|
||||
// server details
|
||||
auto port_spin_box = new QSpinBox;
|
||||
port_spin_box->setMinimum (1);
|
||||
port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
auto group_box_layout = new QFormLayout;
|
||||
group_box_layout->addRow (tr ("Port number:"), port_spin_box);
|
||||
group_box_layout->addRow (tr ("Multicast Group (blank for unicast server):"), multicast_group_line_edit_);
|
||||
auto group_box = new QGroupBox {tr ("Server Details")};
|
||||
group_box->setLayout (group_box_layout);
|
||||
central_layout->addWidget (group_box);
|
||||
|
||||
log_table_view_->setModel (log_);
|
||||
log_table_view_->verticalHeader ()->hide ();
|
||||
central_layout->addWidget (log_table_view_);
|
||||
|
||||
// central widget
|
||||
auto central_widget = new QWidget;
|
||||
central_widget->setLayout (central_layout);
|
||||
|
||||
// main window setup
|
||||
setCentralWidget (central_widget);
|
||||
setDockOptions (AnimatedDocks | AllowNestedDocks | AllowTabbedDocks);
|
||||
setTabPosition (Qt::BottomDockWidgetArea, QTabWidget::North);
|
||||
|
||||
QDockWidget * calls_dock {new QDockWidget {tr ("Calls of Interest"), this}};
|
||||
calls_dock->setAllowedAreas (Qt::RightDockWidgetArea);
|
||||
calls_of_interest_ = new QListWidget {calls_dock};
|
||||
calls_of_interest_->setContextMenuPolicy (Qt::ActionsContextMenu);
|
||||
calls_of_interest_->insertAction (nullptr, add_call_of_interest_action_);
|
||||
connect (add_call_of_interest_action_, &QAction::triggered, [this] () {
|
||||
auto item = new QListWidgetItem {};
|
||||
item->setFlags (item->flags () | Qt::ItemIsEditable);
|
||||
item->setData (Qt::UserRole, QString {});
|
||||
calls_of_interest_->addItem (item);
|
||||
calls_of_interest_->editItem (item);
|
||||
});
|
||||
calls_of_interest_->insertAction (nullptr, delete_call_of_interest_action_);
|
||||
connect (delete_call_of_interest_action_, &QAction::triggered, [this] () {
|
||||
for (auto item : calls_of_interest_->selectedItems ())
|
||||
{
|
||||
auto old_call = item->data (Qt::UserRole);
|
||||
if (old_call.isValid ()) change_highlighting (old_call.toString ());
|
||||
delete item;
|
||||
}
|
||||
});
|
||||
calls_of_interest_->insertAction (nullptr, last_call_of_interest_action_);
|
||||
connect (last_call_of_interest_action_, &QAction::triggered, [this] () {
|
||||
for (auto item : calls_of_interest_->selectedItems ())
|
||||
{
|
||||
auto old_call = item->data (Qt::UserRole);
|
||||
change_highlighting (old_call.toString ());
|
||||
change_highlighting (old_call.toString ()
|
||||
, item->background ().color (), item->foreground ().color (), true);
|
||||
delete item;
|
||||
}
|
||||
});
|
||||
calls_of_interest_->insertAction (nullptr, call_of_interest_bg_colour_action_);
|
||||
connect (call_of_interest_bg_colour_action_, &QAction::triggered, [this] () {
|
||||
for (auto item : calls_of_interest_->selectedItems ())
|
||||
{
|
||||
auto old_call = item->data (Qt::UserRole);
|
||||
auto new_colour = QColorDialog::getColor (item->background ().color ()
|
||||
, this, tr ("Select background color"));
|
||||
if (new_colour.isValid ())
|
||||
{
|
||||
change_highlighting (old_call.toString (), new_colour, item->foreground ().color ());
|
||||
item->setBackground (new_colour);
|
||||
}
|
||||
}
|
||||
});
|
||||
calls_of_interest_->insertAction (nullptr, call_of_interest_fg_colour_action_);
|
||||
connect (call_of_interest_fg_colour_action_, &QAction::triggered, [this] () {
|
||||
for (auto item : calls_of_interest_->selectedItems ())
|
||||
{
|
||||
auto old_call = item->data (Qt::UserRole);
|
||||
auto new_colour = QColorDialog::getColor (item->foreground ().color ()
|
||||
, this, tr ("Select foreground color"));
|
||||
if (new_colour.isValid ())
|
||||
{
|
||||
change_highlighting (old_call.toString (), item->background ().color (), new_colour);
|
||||
item->setForeground (new_colour);
|
||||
}
|
||||
}
|
||||
});
|
||||
connect (calls_of_interest_, &QListWidget::itemChanged, [this] (QListWidgetItem * item) {
|
||||
auto old_call = item->data (Qt::UserRole);
|
||||
auto new_call = item->text ().toUpper ();
|
||||
if (new_call != old_call)
|
||||
{
|
||||
// tell all clients
|
||||
if (old_call.isValid ())
|
||||
{
|
||||
change_highlighting (old_call.toString ());
|
||||
}
|
||||
item->setData (Qt::UserRole, new_call);
|
||||
item->setText (new_call);
|
||||
auto bg = item->listWidget ()->palette ().text ().color ();
|
||||
auto fg = item->listWidget ()->palette ().base ().color ();
|
||||
item->setBackground (bg);
|
||||
item->setForeground (fg);
|
||||
change_highlighting (new_call, bg, fg);
|
||||
}
|
||||
});
|
||||
|
||||
calls_dock->setWidget (calls_of_interest_);
|
||||
addDockWidget (Qt::RightDockWidgetArea, calls_dock);
|
||||
view_menu_->addAction (calls_dock->toggleViewAction ());
|
||||
view_menu_->addSeparator ();
|
||||
|
||||
// connect up server
|
||||
connect (server_, &MessageServer::error, [this] (QString const& message) {
|
||||
QMessageBox::warning (this, QApplication::applicationName (), tr ("Network Error"), message);
|
||||
});
|
||||
connect (server_, &MessageServer::client_opened, this, &MessageAggregatorMainWindow::add_client);
|
||||
connect (server_, &MessageServer::client_closed, this, &MessageAggregatorMainWindow::remove_client);
|
||||
connect (server_, &MessageServer::client_closed, decodes_model_, &DecodesModel::clear_decodes);
|
||||
connect (server_, &MessageServer::client_closed, beacons_model_, &BeaconsModel::clear_decodes);
|
||||
connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time
|
||||
, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence
|
||||
, bool off_air) {
|
||||
decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message
|
||||
, low_confidence, off_air, dock_widgets_[id]->fast_mode ());});
|
||||
connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot);
|
||||
connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes);
|
||||
connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes);
|
||||
connect (decodes_model_, &DecodesModel::reply, server_, &MessageServer::reply);
|
||||
|
||||
// UI behaviour
|
||||
connect (port_spin_box, static_cast<void (QSpinBox::*)(int)> (&QSpinBox::valueChanged)
|
||||
, [this] (port_type port) {server_->start (port);});
|
||||
connect (multicast_group_line_edit_, &QLineEdit::editingFinished, [this, port_spin_box] () {
|
||||
server_->start (port_spin_box->value (), QHostAddress {multicast_group_line_edit_->text ()});
|
||||
});
|
||||
|
||||
port_spin_box->setValue (2237); // start up in unicast mode
|
||||
show ();
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, 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)
|
||||
{
|
||||
QList<QStandardItem *> row;
|
||||
row << new QStandardItem {time_on.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
<< new QStandardItem {time_off.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
<< new QStandardItem {dx_call}
|
||||
<< new QStandardItem {dx_grid}
|
||||
<< new QStandardItem {name}
|
||||
<< new QStandardItem {Radio::frequency_MHz_string (dial_frequency)}
|
||||
<< new QStandardItem {mode}
|
||||
<< new QStandardItem {report_sent}
|
||||
<< new QStandardItem {report_received}
|
||||
<< new QStandardItem {tx_power}
|
||||
<< new QStandardItem {operator_call}
|
||||
<< new QStandardItem {my_call}
|
||||
<< new QStandardItem {my_grid}
|
||||
<< new QStandardItem {comments};
|
||||
log_->appendRow (row);
|
||||
log_table_view_->resizeColumnsToContents ();
|
||||
log_table_view_->horizontalHeader ()->setStretchLastSection (true);
|
||||
log_table_view_->scrollToBottom ();
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::add_client (QString const& id, QString const& version, QString const& revision)
|
||||
{
|
||||
auto dock = new ClientWidget {decodes_model_, beacons_model_, id, version, revision, calls_of_interest_, this};
|
||||
dock->setAttribute (Qt::WA_DeleteOnClose);
|
||||
auto view_action = dock->toggleViewAction ();
|
||||
view_action->setEnabled (true);
|
||||
view_menu_->addAction (view_action);
|
||||
addDockWidget (Qt::BottomDockWidgetArea, dock);
|
||||
connect (server_, &MessageServer::status_update, dock, &ClientWidget::update_status);
|
||||
connect (server_, &MessageServer::decode, dock, &ClientWidget::decode_added);
|
||||
connect (server_, &MessageServer::WSPR_decode, dock, &ClientWidget::beacon_spot_added);
|
||||
connect (server_, &MessageServer::clear_decodes, dock, &ClientWidget::clear_decodes);
|
||||
connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply);
|
||||
connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx);
|
||||
connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text);
|
||||
connect (dock, &ClientWidget::location, server_, &MessageServer::location);
|
||||
connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible);
|
||||
connect (dock, &ClientWidget::highlight_callsign, server_, &MessageServer::highlight_callsign);
|
||||
dock_widgets_[id] = dock;
|
||||
server_->replay (id); // request decodes and status
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::remove_client (QString const& id)
|
||||
{
|
||||
auto iter = dock_widgets_.find (id);
|
||||
if (iter != std::end (dock_widgets_))
|
||||
{
|
||||
(*iter)->close ();
|
||||
dock_widgets_.erase (iter);
|
||||
}
|
||||
}
|
||||
|
||||
MessageAggregatorMainWindow::~MessageAggregatorMainWindow ()
|
||||
{
|
||||
for (auto client : dock_widgets_)
|
||||
{
|
||||
delete client;
|
||||
}
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::change_highlighting (QString const& call, QColor const& bg, QColor const& fg
|
||||
, bool last_only)
|
||||
{
|
||||
for (auto id : dock_widgets_.keys ())
|
||||
{
|
||||
server_->highlight_callsign (id, call, bg, fg, last_only);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_MessageAggregatorMainWindow.cpp"
|
||||
@@ -1,62 +0,0 @@
|
||||
#ifndef WSJTX_MESSAGE_AGGREGATOR_MAIN_WINDOW_MODEL_HPP__
|
||||
#define WSJTX_MESSAGE_AGGREGATOR_MAIN_WINDOW_MODEL_HPP__
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
#include "MessageServer.hpp"
|
||||
|
||||
class QDateTime;
|
||||
class QStandardItemModel;
|
||||
class QMenu;
|
||||
class DecodesModel;
|
||||
class BeaconsModel;
|
||||
class QLineEdit;
|
||||
class QTableView;
|
||||
class ClientWidget;
|
||||
class QListWidget;
|
||||
|
||||
using Frequency = MessageServer::Frequency;
|
||||
|
||||
class MessageAggregatorMainWindow
|
||||
: public QMainWindow
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
MessageAggregatorMainWindow ();
|
||||
~MessageAggregatorMainWindow ();
|
||||
|
||||
Q_SLOT void log_qso (QString const& /*id*/, 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);
|
||||
|
||||
private:
|
||||
void add_client (QString const& id, QString const& version, QString const& revision);
|
||||
void remove_client (QString const& id);
|
||||
void change_highlighting (QString const& call, QColor const& bg = QColor {}, QColor const& fg = QColor {},
|
||||
bool last_only = false);
|
||||
|
||||
// maps client id to widgets
|
||||
using ClientsDictionary = QHash<QString, ClientWidget *>;
|
||||
ClientsDictionary dock_widgets_;
|
||||
|
||||
QStandardItemModel * log_;
|
||||
QMenu * view_menu_;
|
||||
DecodesModel * decodes_model_;
|
||||
BeaconsModel * beacons_model_;
|
||||
MessageServer * server_;
|
||||
QLineEdit * multicast_group_line_edit_;
|
||||
QTableView * log_table_view_;
|
||||
QListWidget * calls_of_interest_;
|
||||
QAction * add_call_of_interest_action_;
|
||||
QAction * delete_call_of_interest_action_;
|
||||
QAction * last_call_of_interest_action_;
|
||||
QAction * call_of_interest_bg_colour_action_;
|
||||
QAction * call_of_interest_fg_colour_action_;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,245 +0,0 @@
|
||||
//
|
||||
// UDPDaemon - an example console application that utilizes the WSJT-X
|
||||
// messaging facility
|
||||
//
|
||||
// This application is only provided as a simple console application
|
||||
// example to demonstrate the WSJT-X messaging facility. It allows
|
||||
// the user to set the server details either as a unicast UDP server
|
||||
// or, if a multicast group address is provided, as a multicast
|
||||
// server. The benefit of the multicast server is that multiple
|
||||
// servers can be active at once each receiving all WSJT-X broadcast
|
||||
// messages and each able to respond to individual WSJT_X clients. To
|
||||
// utilize the multicast group features each WSJT-X client must set
|
||||
// the same multicast group address as the UDP server address for
|
||||
// example 239.255.0.0 for a site local multicast group.
|
||||
//
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDateTime>
|
||||
#include <QTime>
|
||||
#include <QHash>
|
||||
#include <QDebug>
|
||||
|
||||
#include "MessageServer.hpp"
|
||||
#include "Radio.hpp"
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
|
||||
using port_type = MessageServer::port_type;
|
||||
using Frequency = MessageServer::Frequency;
|
||||
|
||||
class Client
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Client (QString const& id, QObject * parent = nullptr)
|
||||
: QObject {parent}
|
||||
, id_ {id}
|
||||
, dial_frequency_ {0u}
|
||||
{
|
||||
}
|
||||
|
||||
Q_SLOT void update_status (QString const& id, 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 (id == id_)
|
||||
{
|
||||
if (f != dial_frequency_)
|
||||
{
|
||||
std::cout << tr ("%1: Dial frequency changed to %2").arg (id_).arg (f).toStdString () << std::endl;
|
||||
dial_frequency_ = f;
|
||||
}
|
||||
if (mode + sub_mode != mode_)
|
||||
{
|
||||
std::cout << tr ("%1: Mode changed to %2").arg (id_).arg (mode + sub_mode).toStdString () << std::endl;
|
||||
mode_ = mode + sub_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime time, qint32 snr
|
||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence, bool off_air)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
|
||||
<< "Dt:" << delta_time << "Df:" << delta_frequency
|
||||
<< "mode:" << mode << "Confidence:" << (low_confidence ? "low" : "high")
|
||||
<< "On air:" << !off_air;
|
||||
std::cout << tr ("%1: Decoded %2").arg (id_).arg (message).toStdString () << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime time, qint32 snr
|
||||
, float delta_time, Frequency delta_frequency, qint32 drift, QString const& callsign
|
||||
, QString const& grid, qint32 power, bool off_air)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
|
||||
<< "Dt:" << delta_time << "Df:" << delta_frequency
|
||||
<< "drift:" << drift;
|
||||
std::cout << tr ("%1: WSPR decode %2 grid %3 power: %4").arg (id_).arg (callsign).arg (grid).arg (power).toStdString ()
|
||||
<< "On air:" << !off_air << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void qso_logged (QString const&client_id, 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 (client_id == id_)
|
||||
{
|
||||
qDebug () << "time_on:" << time_on << "time_off:" << time_off << "dx_call:" << dx_call << "grid:" << dx_grid
|
||||
<< "freq:" << dial_frequency << "mode:" << mode << "rpt_sent:" << report_sent
|
||||
<< "rpt_rcvd:" << report_received << "Tx_pwr:" << tx_power << "comments:" << comments
|
||||
<< "name:" << name << "operator_call:" << operator_call << "my_call:" << my_call
|
||||
<< "my_grid:" << my_grid;
|
||||
std::cout << QByteArray {80, '-'}.data () << '\n';
|
||||
std::cout << tr ("%1: Logged %2 grid: %3 power: %4 sent: %5 recd: %6 freq: %7 time_off: %8 op: %9 my_call: %10 my_grid: %11")
|
||||
.arg (id_).arg (dx_call).arg (dx_grid).arg (tx_power).arg (report_sent).arg (report_received)
|
||||
.arg (dial_frequency).arg (time_off.toString("yyyy-MM-dd hh:mm:ss.z")).arg (operator_call)
|
||||
.arg (my_call).arg (my_grid).toStdString ()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Q_SLOT void logged_ADIF (QString const&client_id, QByteArray const& ADIF)
|
||||
{
|
||||
if (client_id == id_)
|
||||
{
|
||||
qDebug () << "ADIF:" << ADIF;
|
||||
std::cout << QByteArray {80, '-'}.data () << '\n';
|
||||
std::cout << ADIF.data () << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QString id_;
|
||||
Frequency dial_frequency_;
|
||||
QString mode_;
|
||||
};
|
||||
|
||||
class Server
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Server (port_type port, QHostAddress const& multicast_group)
|
||||
: server_ {new MessageServer {this}}
|
||||
{
|
||||
// connect up server
|
||||
connect (server_, &MessageServer::error, [this] (QString const& message) {
|
||||
std::cerr << tr ("Network Error: %1").arg ( message).toStdString () << std::endl;
|
||||
});
|
||||
connect (server_, &MessageServer::client_opened, this, &Server::add_client);
|
||||
connect (server_, &MessageServer::client_closed, this, &Server::remove_client);
|
||||
|
||||
server_->start (port, multicast_group);
|
||||
}
|
||||
|
||||
private:
|
||||
void add_client (QString const& id, QString const& version, QString const& revision)
|
||||
{
|
||||
auto client = new Client {id};
|
||||
connect (server_, &MessageServer::status_update, client, &Client::update_status);
|
||||
connect (server_, &MessageServer::decode, client, &Client::decode_added);
|
||||
connect (server_, &MessageServer::WSPR_decode, client, &Client::beacon_spot_added);
|
||||
connect (server_, &MessageServer::qso_logged, client, &Client::qso_logged);
|
||||
connect (server_, &MessageServer::logged_ADIF, client, &Client::logged_ADIF);
|
||||
clients_[id] = client;
|
||||
server_->replay (id);
|
||||
std::cout << "Discovered WSJT-X instance: " << id.toStdString ();
|
||||
if (version.size ())
|
||||
{
|
||||
std::cout << " v" << version.toStdString ();
|
||||
}
|
||||
if (revision.size ())
|
||||
{
|
||||
std::cout << " (" << revision.toStdString () << ")";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void remove_client (QString const& id)
|
||||
{
|
||||
auto iter = clients_.find (id);
|
||||
if (iter != std::end (clients_))
|
||||
{
|
||||
clients_.erase (iter);
|
||||
(*iter)->deleteLater ();
|
||||
}
|
||||
std::cout << "Removed WSJT-X instance: " << id.toStdString () << std::endl;
|
||||
}
|
||||
|
||||
MessageServer * server_;
|
||||
|
||||
// maps client id to clients
|
||||
QHash<QString, Client *> clients_;
|
||||
};
|
||||
|
||||
#include "UDPDaemon.moc"
|
||||
|
||||
int main (int argc, char * argv[])
|
||||
{
|
||||
QCoreApplication app {argc, argv};
|
||||
try
|
||||
{
|
||||
setlocale (LC_NUMERIC, "C"); // ensure number forms are in
|
||||
// consistent format, do this after
|
||||
// instantiating QApplication so
|
||||
// that GUI has correct l18n
|
||||
|
||||
app.setApplicationName ("WSJT-X UDP Message Server Daemon");
|
||||
app.setApplicationVersion ("1.0");
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription ("\nWSJT-X UDP Message Server Daemon.");
|
||||
auto help_option = parser.addHelpOption ();
|
||||
auto version_option = parser.addVersionOption ();
|
||||
|
||||
QCommandLineOption port_option (QStringList {"p", "port"},
|
||||
app.translate ("UDPDaemon",
|
||||
"Where <PORT> is the UDP service port number to listen on.\n"
|
||||
"The default service port is 2237."),
|
||||
app.translate ("UDPDaemon", "PORT"),
|
||||
"2237");
|
||||
parser.addOption (port_option);
|
||||
|
||||
QCommandLineOption multicast_addr_option (QStringList {"g", "multicast-group"},
|
||||
app.translate ("UDPDaemon",
|
||||
"Where <GROUP> is the multicast group to join.\n"
|
||||
"The default is a unicast server listening on all interfaces."),
|
||||
app.translate ("UDPDaemon", "GROUP"));
|
||||
parser.addOption (multicast_addr_option);
|
||||
|
||||
parser.process (app);
|
||||
|
||||
Server server {static_cast<port_type> (parser.value (port_option).toUInt ()), QHostAddress {parser.value (multicast_addr_option)}};
|
||||
|
||||
return app.exec ();
|
||||
}
|
||||
catch (std::exception const & e)
|
||||
{
|
||||
std::cerr << "Error: " << e.what () << '\n';
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "Unexpected error\n";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
<qresource>@message_aggregator_RESOURCES@
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1 +0,0 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "../icons/windows-icons/wsjtx.ico"
|
||||
@@ -1,13 +0,0 @@
|
||||
/* default stylesheet for the message aggregator application */
|
||||
|
||||
[transmitting="true"] {
|
||||
background-color: yellow
|
||||
}
|
||||
|
||||
[decoding="true"] {
|
||||
background-color: cyan
|
||||
}
|
||||
|
||||
[watchdog_timeout="true"] {
|
||||
background-color: red
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "../icons/windows-icons/wsjtx.ico"
|
||||
@@ -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_MINOR 7)
|
||||
set (WSJTX_VERSION_PATCH 2)
|
||||
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
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "Bands.hpp"
|
||||
#include "FrequencyList.hpp"
|
||||
#include "WsprTxScheduler.h"
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
#include "moc_WSPRBandHopping.cpp"
|
||||
|
||||
@@ -333,7 +335,7 @@ void WSPRBandHopping::set_tx_percent (int new_value)
|
||||
// determine the parameters of the hop, if any
|
||||
auto WSPRBandHopping::next_hop (bool tx_enabled) -> Hop
|
||||
{
|
||||
auto const& now = QDateTime::currentDateTimeUtc ();
|
||||
auto const& now = DriftingDateTime::currentDateTimeUtc ();
|
||||
auto const& date = now.date ();
|
||||
auto year = date.year ();
|
||||
auto month = date.month ();
|
||||
|
||||
@@ -13,23 +13,36 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->labelTxt->setText ("<h2>" + QString {"WSJT-X v"
|
||||
ui->labelTxt->setText ("<h2>" + QString {"JS8Call v"
|
||||
+ QCoreApplication::applicationVersion ()
|
||||
+ " " + revision ()}.simplified () + "</h2><br />"
|
||||
"WSJT-X implements a number of digital modes designed for <br />"
|
||||
"weak-signal Amateur Radio communication. <br /><br />"
|
||||
"© 2001-2018 by Joe Taylor, K1JT, with grateful <br />"
|
||||
"acknowledgment for contributions from AC6SL, AE4JY, <br />"
|
||||
"DJ0OT, G3WDG, G4KLA, G4WJS, IV3NWV, IW3RAB, K3WYC, K9AN, <br />"
|
||||
"KA6MAL, KA9Q, KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR, <br />"
|
||||
"VE1SKY, VK3ACF, VK4BDJ, VK7MO, W4TI, W4TV, and W9MDB.<br /><br />"
|
||||
"WSJT-X is licensed under the terms of Version 3 <br />"
|
||||
"of the GNU General Public License (GPL) <br />"
|
||||
"<a href=" WSJTX_STRINGIZE (PROJECT_HOMEPAGE) ">"
|
||||
"<img src=\":/icon_128x128.png\" /></a>"
|
||||
"<a href=\"https://www.gnu.org/licenses/gpl-3.0.txt\">"
|
||||
"<img src=\":/gpl-v3-logo.svg\" height=\"80\" /><br />"
|
||||
"https://www.gnu.org/licenses/gpl-3.0.txt</a>");
|
||||
|
||||
"JS8Call is a derivative of the WSJT-X application, "
|
||||
"restructured and redesigned for message passing. <br/>"
|
||||
"It is not supported by nor endorsed by the WSJT-X "
|
||||
"development group. <br/>JS8Call is "
|
||||
"licensed under and in accordance with the terms "
|
||||
"of the <a href=\"https://www.gnu.org/licenses/gpl-3.0.txt\">GPLv3 license</a>.<br/>"
|
||||
"The source code modifications are public and can be found in <a href=\"https://bitbucket.org/widefido/wsjtx/\">this repository</a>.<br/><br/>"
|
||||
|
||||
"JS8Call is heavily inspired by WSJT-X, Fldigi, "
|
||||
"and FSQCall <br/>and would not exist without the hard work and "
|
||||
"dedication of the many <br/>developers in the amateur radio "
|
||||
"community.<br /><br />"
|
||||
"JS8Call stands on the shoulder of giants...the takeoff angle "
|
||||
"is better up there.<br /><br />"
|
||||
"A special thanks goes out to the JS8Call development team:<br/><br/><strong>"
|
||||
"KC9QNE, "
|
||||
"KI6SSI, "
|
||||
"K0OG, "
|
||||
"LB9YH, "
|
||||
"M0IAX, "
|
||||
"N0JDS, "
|
||||
"OH8STN, "
|
||||
"VA3OSO, "
|
||||
"VK1MIC, "
|
||||
"W0FW,</strong><br/><br/>and the many other amateur radio operators who have given "
|
||||
"JS8Call a chance.");
|
||||
}
|
||||
|
||||
CAboutDlg::~CAboutDlg()
|
||||
|
||||
@@ -5,8 +5,16 @@
|
||||
<property name="windowModality">
|
||||
<enum>Qt::NonModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>192</width>
|
||||
<height>116</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About WSJT-X</string>
|
||||
<string>About JS8Call</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
|
||||
@@ -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()
|
||||
@@ -12,8 +12,8 @@
|
||||
sodipodi:version="0.32"
|
||||
viewBox="0 0 640 480"
|
||||
version="1.1"
|
||||
sodipodi:docname="tasto_5_architetto_franc_01.svg"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="DragNDrop Background.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
width="100%"
|
||||
height="100%">
|
||||
<defs
|
||||
@@ -27,10 +27,10 @@
|
||||
inkscape:zoom="1.89375"
|
||||
inkscape:cx="227.06271"
|
||||
inkscape:cy="240"
|
||||
inkscape:window-width="1855"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g3" />
|
||||
<g
|
||||
@@ -72,25 +72,6 @@
|
||||
d="m 299.44057,-268.80395 c -9.2,3.806 -5.476,22.395 -5.476,30.261 0,1.951 -23.229,0.93 -26.087,0.93 -8.576,0 -23.012,-2.757 -27.835,6.535 -3.627,6.99 -1.35,19.146 -1.35,26.616 0,8.4 -0.709,17.143 0,25.519 0,13.884 15.395,12.081 24.75,12.081 h 30.326 c 0.616,0 -0.196,23.651 0.363,26.81 1.344,7.601 11.873,10.134 17.171,4.83 1.235,-0.97 2.304,-2.297 3.414,-3.404 6.86,-6.837 13.72,-13.676 20.579,-20.514 7.706,-7.681 15.41,-15.36 23.116,-23.042 4.011,-3.997 10.436,-8.579 12.863,-13.906 3.874,-8.509 -2.996,-14.135 -8.281,-19.426 -7.462,-7.47 -14.926,-14.941 -22.389,-22.411 -7.348,-7.353 -14.693,-14.708 -22.041,-22.061 -5.328,-5.353 -10.368,-12.444 -19.115,-8.826 m -58.942,89.86 v -25.519 c 0,-7.083 -2.537,-20.456 1.757,-26.809 4.938,-7.304 19.854,-4.536 27.283,-4.536 h 17.136 c 1.448,0 7.955,0.999 9.096,0 1.124,-0.984 0,-9.795 0,-11.286 v -14.11 c 0,-6.577 10.11,-8.923 14.281,-4.749 1.512,1.514 3.024,3.027 4.536,4.539 l 46.438,46.479 c 5.123,5.13 13.199,11.335 7.847,19.468 -3.387,5.148 -9.155,9.432 -13.47,13.732 -14.601,14.553 -29.201,29.107 -43.802,43.659 -2.575,2.568 -5.353,4.298 -9.308,3.666 -6.041,-0.967 -6.522,-6.041 -6.522,-10.962 0,-3.029 1.173,-23.3 -1.004,-23.3 h -29.582 c -8.374,-0.01 -24.69,2.6 -24.69,-10.282"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#739b07" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ff7400;fill-opacity:0.77254902;stroke:none;font-family:Purisa;-inkscape-font-specification:Sans Bold"
|
||||
x="316.39532"
|
||||
y="-58.000538"
|
||||
id="text6112"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6114"
|
||||
x="316.39532"
|
||||
y="-58.000538">Drag the icon</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="316.39532"
|
||||
y="-8.0005379"
|
||||
id="tspan6116">onto the link</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="316.39532"
|
||||
y="41.999462"
|
||||
id="tspan6118">to install WSJT-X</tspan></text>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata6108">
|
||||
@@ -107,7 +88,7 @@
|
||||
<dc:title>Openclipart</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
<dc:date>2010-03-28T09:25:56</dc:date>
|
||||
<dc:description>Drawing by Francesco 'Architetto' Rollandin. From OCAL 0.18 release.</dc:description>
|
||||
<dc:source>http://openclipart.org/detail/34711/architetto----tasto-5-by-anonymous</dc:source>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="1024"
|
||||
height="1024"
|
||||
viewBox="0 0 270.93333 270.93334"
|
||||
version="1.1"
|
||||
id="svg16"
|
||||
inkscape:export-filename="/home/jordan/bitmap.png"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="icon_1024.svg">
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="linearGradient6001"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5999" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.48333333"
|
||||
inkscape:cx="1350"
|
||||
inkscape:cy="512"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
units="px"
|
||||
inkscape:pagecheckerboard="true" />
|
||||
<metadata
|
||||
id="metadata13">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-26.06665)">
|
||||
<g
|
||||
id="g6030"
|
||||
transform="matrix(1.5635065,0,0,1.5635065,-28.822499,6.8392367)">
|
||||
<circle
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
r="81.642853"
|
||||
cy="98.940475"
|
||||
cx="105.07738"
|
||||
id="path18" />
|
||||
<text
|
||||
id="text24"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:176.3888855px;font-family:wasy10;-inkscape-font-specification:wasy10;fill:#000000;stroke-width:0.17748445"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
id="tspan22"
|
||||
sodipodi:role="line">⌁</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 33.866666 33.866667"
|
||||
version="1.1"
|
||||
id="svg16"
|
||||
inkscape:export-filename="/home/jordan/bitmap.png"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="icon_1024.svg">
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="linearGradient6001"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5999" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.48333333"
|
||||
inkscape:cx="1350"
|
||||
inkscape:cy="512"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
units="px"
|
||||
inkscape:pagecheckerboard="true" />
|
||||
<metadata
|
||||
id="metadata13">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-263.13332)">
|
||||
<g
|
||||
id="g6030"
|
||||
transform="matrix(0.19543832,0,0,0.19543832,-3.6028125,260.72988)">
|
||||
<circle
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
r="81.642853"
|
||||
cy="98.940475"
|
||||
cx="105.07738"
|
||||
id="path18" />
|
||||
<text
|
||||
id="text24"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:176.3888855px;font-family:wasy10;-inkscape-font-specification:wasy10;fill:#000000;stroke-width:0.17748445"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
id="tspan22"
|
||||
sodipodi:role="line">⌁</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 115 KiB |
@@ -3,8 +3,8 @@
|
||||
#
|
||||
# Windows
|
||||
#
|
||||
inkscape -z -e /tmp/image-0.png wsjt_globe_128x128.svg
|
||||
inkscape -z -e /tmp/image-1.png wsjtx_globe_1024x1024.svg
|
||||
inkscape -z -e /tmp/image-0.png icon_128.svg
|
||||
inkscape -z -e /tmp/image-1.png icon_1024.svg
|
||||
convert '/tmp/image-%d.png[0-1]' -background transparent \
|
||||
\( -clone 0 -resize 16 -colors 256 -compress none \) \
|
||||
\( -clone 0 -resize 20 -colors 256 -compress none \) \
|
||||
@@ -25,41 +25,42 @@ convert '/tmp/image-%d.png[0-1]' -background transparent \
|
||||
\( -clone 1 -resize 128 -compress none \) \
|
||||
\( -clone 1 -resize 256 -compress Zip \) \
|
||||
-delete 1 -delete 0 \
|
||||
-alpha remove ../icons/windows-icons/wsjtx.ico
|
||||
-alpha remove ../icons/windows-icons/js8call.ico
|
||||
rm /tmp/image-0.png /tmp/image-1.png
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/windows-icons/wsjtx.ico
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/windows-icons/js8call.ico
|
||||
#
|
||||
inkscape -z -e /dev/stdout -w 150 -h 57 -b white installer_logo.svg | tail -n +4 | \
|
||||
convert png:- -resize 150x57 +matte BMP3:../icons/windows-icons/installer_logo.bmp
|
||||
#inkscape -z -e /dev/stdout -w 150 -h 57 -b white installer_logo.svg | tail -n +4 | \
|
||||
# convert png:- -resize 150x57 +matte BMP3:../icons/windows-icons/installer_logo.bmp
|
||||
convert png:installer_logo.svg.png -resize 150x57 +matte BMP3:../icons/windows-icons/installer_logo.bmp
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/windows-icons/installer_logo.bmp
|
||||
|
||||
#
|
||||
# Mac
|
||||
#
|
||||
mkdir -p ../icons/Darwin/wsjtx.iconset
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_16x16.png -w 16 -h 16 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_16x16@2x.png -w 32 -h 32 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_32x32.png -w 32 -h 32 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_32x32@2x.png -w 64 -h 64 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_128x128.png -w 128 -h 128 wsjtx_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_128x128@2x.png -w 256 -h 256 wsjtx_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_256x256.png -w 256 -h 256 wsjtx_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_256x256@2x.png -w 512 -h 512 wsjtx_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_512x512.png -w 512 -h 512 wsjtx_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjtx.iconset/icon_512x512@2x.png -w 1024 -h 1024 wsjtx_globe_1024x1024.svg
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/Darwin/wsjtx.iconset/*
|
||||
mkdir -p ../icons/Darwin/JS8Call.iconset
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_16x16.png -w 16 -h 16 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_16x16@2x.png -w 32 -h 32 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_32x32.png -w 32 -h 32 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_32x32@2x.png -w 64 -h 64 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_128x128.png -w 128 -h 128 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_128x128@2x.png -w 256 -h 256 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_256x256.png -w 256 -h 256 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_256x256@2x.png -w 512 -h 512 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_512x512.png -w 512 -h 512 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/JS8Call.iconset/icon_512x512@2x.png -w 1024 -h 1024 icon_1024.svg
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/Darwin/JS8Call.iconset/*
|
||||
# generic globe iconset for utilities
|
||||
mkdir -p ../icons/Darwin/wsjt.iconset
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_16x16.png -w 16 -h 16 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_16x16@2x.png -w 32 -h 32 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_32x32.png -w 32 -h 32 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_32x32@2x.png -w 64 -h 64 wsjt_globe_128x128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_128x128.png -w 128 -h 128 wsjt_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_128x128@2x.png -w 256 -h 256 wsjt_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_256x256.png -w 256 -h 256 wsjt_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_256x256@2x.png -w 512 -h 512 wsjt_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_512x512.png -w 512 -h 512 wsjt_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_512x512@2x.png -w 1024 -h 1024 wsjt_globe_1024x1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_16x16.png -w 16 -h 16 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_16x16@2x.png -w 32 -h 32 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_32x32.png -w 32 -h 32 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_32x32@2x.png -w 64 -h 64 icon_128.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_128x128.png -w 128 -h 128 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_128x128@2x.png -w 256 -h 256 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_256x256.png -w 256 -h 256 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_256x256@2x.png -w 512 -h 512 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_512x512.png -w 512 -h 512 icon_1024.svg
|
||||
inkscape -z -e ../icons/Darwin/wsjt.iconset/icon_512x512@2x.png -w 1024 -h 1024 icon_1024.svg
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/Darwin/wsjt.iconset/*
|
||||
#
|
||||
inkscape -z -e "../icons/Darwin/DragNDrop Background.png" -w 640 -h 480 -b white "DragNDrop Background.svg"
|
||||
@@ -68,5 +69,5 @@ identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' "../icons/Darwin/DragNDrop Ba
|
||||
#
|
||||
# KDE & Gnome
|
||||
#
|
||||
inkscape -z -e ../icons/Unix/wsjtx_icon.png -w 128 -h 128 wsjtx_globe_1024x1024.svg
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/Unix/wsjtx_icon.png
|
||||
inkscape -z -e ../icons/Unix/js8call_icon.png -w 128 -h 128 icon_1024.svg
|
||||
identify -format '%f %p/%n %m %C/%Q %r %G %A %z\n' ../icons/Unix/js8call_icon.png
|
||||
|
||||
@@ -1,577 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/bill/Dropbox/src/wsjtx-dev/icons/windows-icons/icon_1024x1024.png"
|
||||
version="1.1"
|
||||
width="1024"
|
||||
sodipodi:version="0.32"
|
||||
sodipodi:docname="wsjtx_globe_1024x1024.svg"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
id="svg1432"
|
||||
height="1024">
|
||||
<sodipodi:namedview
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
id="base"
|
||||
inkscape:current-layer="svg1432"
|
||||
inkscape:cx="512"
|
||||
inkscape:cy="512"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-height="858"
|
||||
inkscape:window-width="1114"
|
||||
inkscape:window-x="72"
|
||||
inkscape:window-y="31"
|
||||
inkscape:zoom="0.69433594"
|
||||
pagecolor="#ffffff"
|
||||
showborder="true"
|
||||
showguides="true"
|
||||
showgrid="false"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:showpageshadow="false" />
|
||||
<metadata
|
||||
id="metadata3060">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title></dc:title>
|
||||
<dc:description>Simple globe centered on North America</dc:description>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>earth globe northamerica</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:publisher>
|
||||
<cc:Agent
|
||||
rdf:about="http://www.openclipart.org/">
|
||||
<dc:title>Open Clip Art Library</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Dan Gerhrads</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>Dan Gerhrads</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:date>May 1, 2005</dc:date>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<cc:license
|
||||
rdf:resource="http://web.resource.org/cc/PublicDomain" />
|
||||
<dc:language>en</dc:language>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://web.resource.org/cc/PublicDomain">
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs1759">
|
||||
<linearGradient
|
||||
id="linearGradient37658">
|
||||
<stop
|
||||
style="stop-color:#2f7aff;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop37660" />
|
||||
<stop
|
||||
style="stop-color:#0000b3;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop37662" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient20137">
|
||||
<stop
|
||||
style="stop-color:#00bf00;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop20139" />
|
||||
<stop
|
||||
style="stop-color:#007500;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop20141" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient20143"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient37658"
|
||||
r="112.3373"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient37664"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.806632,1.239722)"
|
||||
fy="270.08731"
|
||||
fx="221.61394"
|
||||
cy="270.08731"
|
||||
cx="221.61394" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1902"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1904"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1906"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1908"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1910"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1912"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1914"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1916"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1918"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1920"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient37658-427"
|
||||
r="112.3373"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient37664-403"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.806632,1.239722)"
|
||||
fy="270.08731"
|
||||
fx="221.61394"
|
||||
cy="270.08731"
|
||||
cx="221.61394" />
|
||||
<linearGradient
|
||||
id="linearGradient37658-427">
|
||||
<stop
|
||||
style="stop-color:#488afe;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7178" />
|
||||
<stop
|
||||
style="stop-color:#0000cc;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7180" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-396"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1902-893"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-396">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7184" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7186" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-527"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1904-666"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-527">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7190" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7192" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-774"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1906-717"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-774">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7196" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7198" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-253"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1908-922"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-253">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7202" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7204" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-972"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1910-261"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-972">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7208" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7210" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-945"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1912-713"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-945">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7214" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7216" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-600"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1914-146"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-600">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7220" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7222" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-196"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1916-817"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-196">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7226" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7228" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-388"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1918-23"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-388">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7232" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7234" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-202"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1920-260"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-202">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7238" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7240" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-151"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient20143-884"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-151">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7244" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7246" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<desc
|
||||
id="desc1434">wmf2svg</desc>
|
||||
<polyline
|
||||
transform="matrix(2.2285926,-3.5745108,2.3232002,1.4484387,-677.00545,692.67468)"
|
||||
style="fill:url(#radialGradient37664-403);fill-opacity:1;stroke:#0c0c0c;stroke-width:0.6875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4"
|
||||
points="103.191467,409.292114 100.730545,403.134064 98.525299,396.927094 96.543777,390.573547 94.785973,384.171082 93.219925,377.622009 91.909569,371.072968 90.790962,364.426147 89.928040,357.779327 89.256882,351.083649 88.777481,344.387970 88.521805,337.692261 88.489838,330.947693 88.681602,324.300873 89.033165,317.605194 89.640404,311.007263 90.407448,304.458221 91.398209,298.006897 92.580727,291.604431 93.986977,285.299744 95.553017,279.092804 97.342781,272.983582 99.324303,267.069916 101.465622,261.253937 103.830666,255.584595 106.387474,250.110733 109.104080,244.783508 112.012444,239.700668 115.112572,234.764420 118.404449,230.072571 121.856140,225.625061 125.499588,221.373062 129.302826,217.414291 133.265884,213.748779 137.260895,210.425354 141.351776,207.444077 145.506577,204.804901 149.725311,202.556717 153.975983,200.601776 158.258652,198.988937 162.573242,197.718231 166.919815,196.789627 171.266373,196.154266 175.644897,195.909912 179.991470,195.909912 184.338043,196.300888 188.652649,196.985123 192.967270,197.962585 197.217941,199.233307 201.468628,200.846130 205.623444,202.801071 209.746277,205.000397 213.805222,207.541809 217.768265,210.376495 221.667389,213.504395 225.470627,216.876678 229.177994,220.591064 232.789490,224.598709 236.273132,228.850708 239.628937,233.444839 242.856903,238.283325 245.957031,243.366180 248.929321,248.791153 251.709839,254.411621 254.362534,260.374207 256.791504,266.483398 258.996704,272.739227 261.010223,279.043915 262.768005,285.495270 264.302094,291.995453 265.644409,298.593384 266.731079,305.191315 267.625946,311.838104 268.297119,318.533813 268.744537,325.278351 269.000244,331.974030 269.032166,338.669739 268.872375,345.365448 268.488861,352.012238 267.913574,358.610168 267.114594,365.159241 266.123840,371.659424 264.941284,378.061890 263.567017,384.366577 261.969025,390.573547 260.211212,396.633850 258.229706,402.596436 256.056396,408.412384 253.723328,414.032837 251.166504,419.555603 248.449905,424.833923 245.509598,429.965668 242.409470,434.853027 239.149536,439.593750 235.697845,444.041260 232.054413,448.244385 228.219193,452.252045 224.288116,455.917542 220.261139,459.240967 216.170258,462.173401 212.015442,464.812561 207.828674,467.109589 203.577988,469.064545 199.263397,470.628510 194.948776,471.899200 190.634186,472.876678 186.255646,473.463196 181.909073,473.756439 177.562500,473.707550 173.215942,473.365448 168.869370,472.681213 164.586731,471.703735 160.304077,470.384155 156.085358,468.771332 151.898590,466.865265 147.807709,464.617065 143.748779,462.124512 139.753769,459.289856 135.854645,456.161926 132.051392,452.740753 128.344025,449.026367 124.764503,445.067596 121.280853,440.766724 117.893089,436.221466 114.665123,431.382996 111.565002,426.251282 108.624680,420.875153 105.812187,415.205811 103.191467,409.292114 "
|
||||
id="polyline1560" />
|
||||
<g
|
||||
transform="matrix(4.1610916,0,0,4.1610916,-268.34786,-716.6628)"
|
||||
style="fill:url(#radialGradient1902-893);fill-opacity:1;fill-rule:evenodd"
|
||||
inkscape:label="Continents"
|
||||
id="Continents">
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1904-666);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="132.818436,384.610931 131.827682,384.953064 128.184235,388.227600 126.074867,388.667450 123.422180,385.441803 120.417938,385.832794 117.126053,389.107300 116.838409,393.896912 116.902328,400.641479 115.655891,409.292114 114.409447,415.352448 115.432167,418.235992 113.578484,420.386444 111.053642,420.924042 109.903076,422.732361 109.871117,423.172241 116.295090,433.728943 123.262383,443.161530 130.836914,451.421204 140.904327,460.071808 151.195465,466.425385 153.528549,464.470428 157.683365,463.248596 162.509323,463.688446 165.321808,463.835083 165.577484,459.387573 165.066132,457.628113 162.381485,454.793457 158.162750,448.244385 155.094604,442.526184 156.884354,433.680054 153.496597,425.664764 151.738800,419.017975 150.811951,410.220703 147.743790,405.479980 144.579727,397.953430 142.438416,395.851868 141.447662,389.058441 138.858887,386.419281 135.886597,384.855316 133.968994,384.219940 133.201950,380.994293 131.667877,376.351288 131.923553,370.926331 132.850403,369.069122 135.407196,368.140533 137.292847,366.625458 137.452652,362.911041 136.557755,358.316925 134.736038,353.967194 135.886597,352.158844 138.123810,351.914490 141.255890,349.812927 141.223938,346.245178 139.050644,343.557098 136.973236,343.654846 135.471115,341.602142 134.863876,337.643402 135.407196,330.947693 138.219681,327.575439 141.191971,325.571625 145.890106,326.158081 148.510818,330.361237 149.469635,333.635773 149.565506,336.421570 150.588226,338.327637 152.314072,339.891571 153.656403,344.045837 154.135788,348.737701 152.665634,353.771698 151.578995,357.730469 152.985229,359.587646 155.094604,356.557495 156.468872,353.234070 159.153519,351.572388 161.870132,351.474609 165.865143,353.967194 168.517807,355.237885 171.458130,352.696472 175.389221,351.425751 178.457397,351.621246 179.416199,352.940857 181.301834,352.403229 184.497833,352.452087 185.968002,353.918335 186.095840,356.704102 187.949539,357.143951 190.602203,359.392151 192.551788,361.004974 193.670380,358.610168 191.912582,355.482269 191.561020,353.576202 193.095093,351.767883 192.583740,349.030945 190.442413,347.906860 188.620697,346.147400 189.259888,345.169952 191.976501,346.049652 195.044662,348.835449 196.259140,351.230255 198.624191,353.771698 200.733551,353.282928 202.363510,350.057312 203.609955,343.996979 204.153275,334.710999 202.906830,330.752228 202.331558,328.406281 203.258408,324.594147 202.459396,316.676605 201.053146,314.819397 198.496353,317.311981 195.300339,320.781982 194.788971,323.567780 192.871368,323.518921 189.739288,325.669373 186.894852,327.477692 187.342285,323.470032 188.524796,319.755646 190.666138,317.311981 190.314575,313.450958 189.132050,308.123718 190.090851,304.898071 193.734299,301.965637 197.601471,302.063385 202.107834,303.773987 205.559525,305.875519 207.796722,306.217651 208.435928,302.698761 206.678116,300.548309 206.038925,296.980560 207.796722,294.585724 209.490601,292.581909 208.627686,290.529205 205.783249,292.386414 203.961517,291.555573 204.057388,289.258514 207.189484,286.130615 208.787491,282.953796 208.627686,279.532684 209.874130,275.427277 208.276123,272.152740 206.198730,271.273010 205.783249,275.231781 204.185242,277.479980 203.929565,281.927460 201.788239,283.393677 202.715073,269.513580 203.546036,261.938171 204.888351,257.050812 206.997711,254.998108 209.426682,251.283707 209.171005,248.595657 207.541046,244.734634 206.262650,243.708313 205.687363,241.362366 204.600723,239.211929 202.715073,239.798416 201.276871,239.896149 200.030426,234.959930 197.697342,233.395966 194.916824,233.884705 192.743546,234.715546 191.976501,231.929764 192.264130,228.068741 190.698090,230.903412 191.145538,235.986282 191.912582,241.362366 192.104340,246.347473 190.154770,250.208496 187.406204,253.238663 182.548279,255.780090 177.338791,257.979401 173.695343,260.911804 171.745789,262.866760 169.956009,265.603668 166.696106,264.919464 162.924805,265.066071 158.290604,266.092438 153.464630,269.220306 146.944778,274.352051 145.091095,277.479980 141.671371,283.442566 138.954773,288.036682 135.918564,293.950378 135.119568,298.593384 135.503082,301.476929 136.334045,297.420410 138.091858,294.048126 140.361008,290.871338 142.310577,287.987793 143.365265,289.502869 141.959015,292.190948 138.283615,298.055786 135.087601,306.071045 132.946274,309.492188 130.900833,310.176422 129.686356,314.330688 130.069870,319.755646 128.919312,329.628113 129.494598,334.515503 130.677109,341.797638 131.603958,350.546021 131.540024,355.482269 130.964752,360.565125 128.280106,366.772064 129.047150,373.125641 129.654404,377.084412 131.476105,380.456665 132.818436,384.610931 "
|
||||
id="polyline1460" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1906-717);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="144.579727,355.237885 146.497345,357.241699 147.583984,362.324585 148.638672,368.384918 149.980988,372.539154 150.364502,377.035553 148.798477,377.279877 146.753021,373.467743 146.976746,368.433777 146.593216,362.959930 144.579727,355.237885 "
|
||||
id="polyline1464" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1908-922);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="150.108826,378.892731 148.830429,379.870209 149.309830,383.584595 150.172745,386.614777 152.633667,390.964508 152.505829,386.565887 153.336792,386.077148 153.017197,383.780090 150.108826,378.892731 "
|
||||
id="polyline1468" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1910-261);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="201.181000,353.820557 200.797470,356.459747 200.413956,361.053864 199.966507,365.990082 199.007706,368.238281 196.866379,363.204285 197.921066,357.681580 199.103592,354.895782 201.181000,353.820557 "
|
||||
id="polyline1472" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1912-713);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="204.632675,320.342133 203.993469,316.774353 202.906830,312.668976 206.230682,314.575043 208.883362,312.277985 209.842163,309.052338 208.915314,303.822876 208.563766,299.961853 209.874130,294.487976 212.430923,295.514343 213.261887,299.570862 213.581497,305.386810 213.837173,310.958405 212.111328,314.917175 211.951538,317.018738 212.335052,321.466217 210.800964,325.913727 208.691605,325.376099 206.454407,326.646820 205.016205,324.203125 204.632675,320.342133 "
|
||||
id="polyline1476" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1914-146);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="213.773254,334.955322 213.709335,340.820160 213.869125,343.263885 216.362015,346.636139 219.526062,350.594910 218.695099,344.632324 219.685867,341.406677 222.722061,339.060730 227.835663,334.662109 230.648163,335.786194 233.332809,333.147003 234.355515,326.011475 234.675125,319.218048 233.556534,312.522369 233.588486,306.071045 231.511078,300.646057 228.890350,297.420410 226.365509,296.980560 225.246902,294.830109 226.365509,293.461639 225.023193,290.235992 222.338547,287.401337 220.964264,289.698364 217.352783,290.675842 216.330063,294.292480 216.362015,299.375336 220.644653,297.469269 222.754028,297.958038 220.708588,301.623535 219.941544,306.852997 220.293106,310.714020 219.845657,317.654083 219.078629,323.909912 214.955765,329.237122 215.083618,333.000397 213.773254,334.955322 "
|
||||
id="polyline1480" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1916-817);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="232.533813,338.767487 230.200729,341.748779 229.401718,344.436798 229.721313,347.662476 233.460648,348.542206 237.040161,346.929382 237.231934,342.872864 235.378250,340.478088 233.620453,340.282562 232.533813,338.767487 "
|
||||
id="polyline1484" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1918-23);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="264.877380,375.813690 262.991730,379.919098 260.371002,382.167236 258.645172,385.148529 258.645172,389.693817 256.887360,391.062256 255.161514,388.911804 254.522308,386.956848 252.732559,385.197418 253.339798,391.697632 251.709839,392.332977 249.792236,387.738861 248.322067,389.840393 246.724060,393.017212 244.327072,395.412018 242.952774,399.664001 241.514587,403.329529 241.067139,407.337158 239.565018,407.190552 238.318573,407.777039 235.665894,409.096649 233.173004,407.679291 233.141052,401.570068 234.707092,399.712891 235.122574,395.705231 237.231934,393.652588 239.692856,394.434540 241.834183,392.039734 240.843414,387.152374 239.980499,385.099670 240.907349,382.265015 244.550781,379.332581 247.043671,372.685760 247.139542,368.384918 249.121078,365.110352 252.125320,361.151611 254.202728,353.967194 256.503845,350.399414 255.992477,346.684998 255.864655,342.335266 255.832672,339.744965 254.586243,339.353973 254.074875,342.139771 251.581985,340.722412 252.189240,343.654846 251.997467,347.760223 251.294357,352.647583 251.486115,357.632721 248.897354,354.993530 246.915833,355.335632 246.020950,351.670135 245.733307,346.489502 247.778748,340.233704 248.002472,336.763672 247.586990,329.774750 247.299347,324.545258 248.705597,319.315765 251.230438,321.319580 254.234680,326.451324 255.608963,324.154266 255.097595,321.417358 253.915070,321.612854 252.253159,317.702942 254.202728,316.774353 253.883118,313.548676 254.714081,310.469666 254.746033,303.969452 255.001724,293.999268 253.947052,293.070679 252.349030,292.777405 250.495346,290.382599 250.303589,287.938934 249.312836,284.077911 247.235428,279.679291 245.381744,278.261963 242.920822,273.912201 241.546539,269.122559 241.035172,265.408173 242.345535,263.502106 240.555771,258.761383 238.734055,257.979401 236.560776,253.336411 234.131805,249.573120 232.501846,251.185959 230.648163,249.768631 228.315079,245.272247 226.653152,244.343658 225.438675,246.494095 223.808701,245.174515 220.964264,239.896149 219.430176,240.775894 217.672379,242.193222 216.170258,241.069122 212.718582,239.945023 210.257645,239.114182 207.509079,237.647964 205.527557,234.422318 206.805954,234.471191 209.362778,234.520065 210.225693,233.004974 208.979248,230.072571 209.810211,226.993515 210.737045,224.109970 213.325806,224.794220 215.722824,225.967178 216.745544,227.873245 219.781738,227.531128 222.114822,224.549835 224.032425,226.553665 226.844925,229.241714 229.785248,226.700287 230.136795,223.425751 229.721313,220.933197 236.592728,229.290573 241.898102,236.768250 246.564270,244.490280 251.837677,254.704865 255.960541,264.332947 260.115326,276.258118 264.302094,291.995453 267.210449,308.514740 268.393005,320.537628 269.000244,333.538025 268.840424,345.169952 268.201202,356.557495 266.794983,367.358551 265.516571,374.933960 264.877380,375.813690 "
|
||||
id="polyline1488" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1920-260);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="244.774506,357.779327 243.304337,356.313110 242.345535,358.512421 241.131058,362.666687 239.916580,364.817108 238.062897,367.945038 237.615448,372.930145 238.414459,375.324951 239.373245,373.125641 239.852661,368.727020 240.683624,367.602905 241.067139,371.121826 241.290848,375.129456 241.834183,378.452850 243.336304,376.986664 243.528061,376.937775 243.719818,376.888916 243.911591,376.791168 244.071396,376.644531 244.390976,376.351288 244.678635,376.009186 244.934311,375.618195 245.126068,375.324951 245.221939,375.129456 245.285858,375.031708 245.253906,372.490265 244.486862,365.159241 244.199219,361.884705 244.774506,357.779327 "
|
||||
id="polyline1492" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient20143-884);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="262.192749,389.449432 260.115326,391.160004 258.261658,394.287933 256.663635,394.532288 255.992477,392.968323 255.065643,395.802979 253.851151,400.885864 250.783005,404.209290 250.175766,401.276855 249.344803,399.810638 245.573502,402.889679 242.537292,406.213104 240.747543,406.995056 238.126801,409.878601 236.049423,409.976349 233.748291,411.002716 231.606964,415.010315 228.986237,420.826294 226.333542,423.123352 220.996231,428.059601 216.617691,433.680054 213.485611,439.349396 210.385483,446.582703 209.171005,453.278381 210.353516,458.605591 214.220703,458.654480 216.777496,458.752228 218.535294,460.560547 223.648911,456.504028 228.187241,452.252045 232.693619,447.511292 237.775253,441.402100 243.400223,433.386810 247.906586,425.811401 251.677872,418.529236 255.161514,410.611694 258.069885,403.134064 260.690613,394.923279 262.192749,389.449432 "
|
||||
id="polyline1496" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 32 KiB |
@@ -1,839 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="128"
|
||||
id="svg1432"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="wsjtx_globe_128x128.svg"
|
||||
sodipodi:version="0.32"
|
||||
width="128"
|
||||
version="1.1">
|
||||
<sodipodi:namedview
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
id="base"
|
||||
inkscape:current-layer="svg1432"
|
||||
inkscape:cx="64"
|
||||
inkscape:cy="64"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-height="1027"
|
||||
inkscape:window-width="1846"
|
||||
inkscape:window-x="72"
|
||||
inkscape:window-y="24"
|
||||
inkscape:zoom="6.875"
|
||||
pagecolor="#ffffff"
|
||||
showborder="false"
|
||||
showguides="true"
|
||||
showgrid="false"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:snap-from-guide="true" />
|
||||
<metadata
|
||||
id="metadata3060">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title />
|
||||
<dc:description>Simple globe centered on North America</dc:description>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>earth globe northamerica</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:publisher>
|
||||
<cc:Agent
|
||||
rdf:about="http://www.openclipart.org/">
|
||||
<dc:title>Open Clip Art Library</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Dan Gerhrads</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>Dan Gerhrads</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:date>May 1, 2005</dc:date>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<cc:license
|
||||
rdf:resource="http://web.resource.org/cc/PublicDomain" />
|
||||
<dc:language>en</dc:language>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://web.resource.org/cc/PublicDomain">
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs1759">
|
||||
<linearGradient
|
||||
id="linearGradient37658">
|
||||
<stop
|
||||
id="stop37660"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#619afe;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop37662"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#0000e5;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient20137">
|
||||
<stop
|
||||
id="stop20139"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#00f100;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop20141"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00a700;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient20143"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="221.61394"
|
||||
cy="270.08731"
|
||||
fx="221.61394"
|
||||
fy="270.08731"
|
||||
gradientTransform="scale(0.806632,1.239722)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient37664"
|
||||
inkscape:collect="always"
|
||||
r="112.3373"
|
||||
xlink:href="#linearGradient37658" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1902"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1904"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1906"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1908"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1910"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1912"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1914"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1916"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1918"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1920"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137" />
|
||||
<radialGradient
|
||||
cx="221.61394"
|
||||
cy="270.08731"
|
||||
fx="221.61394"
|
||||
fy="270.08731"
|
||||
gradientTransform="scale(0.806632,1.239722)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient37664-284"
|
||||
inkscape:collect="always"
|
||||
r="112.3373"
|
||||
xlink:href="#linearGradient37658-332" />
|
||||
<linearGradient
|
||||
id="linearGradient37658-332">
|
||||
<stop
|
||||
id="stop8375"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#7aaafe;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8377"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#0000fe;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1902-108"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-970" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-970">
|
||||
<stop
|
||||
id="stop8381"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8383"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1904-972"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-24" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-24">
|
||||
<stop
|
||||
id="stop8387"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8389"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1906-828"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-376" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-376">
|
||||
<stop
|
||||
id="stop8393"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8395"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1908-502"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-289" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-289">
|
||||
<stop
|
||||
id="stop8399"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8401"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1910-187"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-879" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-879">
|
||||
<stop
|
||||
id="stop8405"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8407"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1912-38"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-891" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-891">
|
||||
<stop
|
||||
id="stop8411"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8413"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1914-119"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-529" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-529">
|
||||
<stop
|
||||
id="stop8417"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8419"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1916-825"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-469" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-469">
|
||||
<stop
|
||||
id="stop8423"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8425"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1918-387"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-981" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-981">
|
||||
<stop
|
||||
id="stop8429"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8431"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1920-264"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-421" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-421">
|
||||
<stop
|
||||
id="stop8435"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8437"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient20143-627"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-58" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-58">
|
||||
<stop
|
||||
id="stop8441"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#0bfe0b;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8443"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00c000;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="221.61394"
|
||||
cy="270.08731"
|
||||
fx="221.61394"
|
||||
fy="270.08731"
|
||||
gradientTransform="scale(0.806632,1.239722)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient37664-284-781"
|
||||
inkscape:collect="always"
|
||||
r="112.3373"
|
||||
xlink:href="#linearGradient37658-332-354" />
|
||||
<linearGradient
|
||||
id="linearGradient37658-332-354">
|
||||
<stop
|
||||
id="stop8612"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#93bafe;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8614"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#1818ff;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1902-108-124"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-970-892" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-970-892">
|
||||
<stop
|
||||
id="stop8618"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8620"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1904-972-786"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-24-119" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-24-119">
|
||||
<stop
|
||||
id="stop8624"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8626"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1906-828-861"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-376-597" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-376-597">
|
||||
<stop
|
||||
id="stop8630"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8632"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1908-502-115"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-289-824" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-289-824">
|
||||
<stop
|
||||
id="stop8636"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8638"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1910-187-480"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-879-315" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-879-315">
|
||||
<stop
|
||||
id="stop8642"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8644"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1912-38-980"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-891-460" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-891-460">
|
||||
<stop
|
||||
id="stop8648"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8650"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1914-119-179"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-529-932" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-529-932">
|
||||
<stop
|
||||
id="stop8654"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8656"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1916-825-422"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-469-24" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-469-24">
|
||||
<stop
|
||||
id="stop8660"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8662"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1918-387-755"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-981-521" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-981-521">
|
||||
<stop
|
||||
id="stop8666"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8668"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient1920-264-381"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-421-297" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-421-297">
|
||||
<stop
|
||||
id="stop8672"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8674"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
cx="202.06305"
|
||||
cy="297.1124"
|
||||
fx="205.17723"
|
||||
fy="298.37747"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient20143-627-23"
|
||||
inkscape:collect="always"
|
||||
r="188.61865"
|
||||
xlink:href="#linearGradient20137-58-615" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-58-615">
|
||||
<stop
|
||||
id="stop8678"
|
||||
offset="0.0000000"
|
||||
style="stop-color:#24fe24;stop-opacity:1.0000000;" />
|
||||
<stop
|
||||
id="stop8680"
|
||||
offset="1.0000000"
|
||||
style="stop-color:#00d900;stop-opacity:1.0000000;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<desc
|
||||
id="desc1434">wmf2svg</desc>
|
||||
<polyline
|
||||
id="polyline1560"
|
||||
points="103.191467,409.292114 100.730545,403.134064 98.525299,396.927094 96.543777,390.573547 94.785973,384.171082 93.219925,377.622009 91.909569,371.072968 90.790962,364.426147 89.928040,357.779327 89.256882,351.083649 88.777481,344.387970 88.521805,337.692261 88.489838,330.947693 88.681602,324.300873 89.033165,317.605194 89.640404,311.007263 90.407448,304.458221 91.398209,298.006897 92.580727,291.604431 93.986977,285.299744 95.553017,279.092804 97.342781,272.983582 99.324303,267.069916 101.465622,261.253937 103.830666,255.584595 106.387474,250.110733 109.104080,244.783508 112.012444,239.700668 115.112572,234.764420 118.404449,230.072571 121.856140,225.625061 125.499588,221.373062 129.302826,217.414291 133.265884,213.748779 137.260895,210.425354 141.351776,207.444077 145.506577,204.804901 149.725311,202.556717 153.975983,200.601776 158.258652,198.988937 162.573242,197.718231 166.919815,196.789627 171.266373,196.154266 175.644897,195.909912 179.991470,195.909912 184.338043,196.300888 188.652649,196.985123 192.967270,197.962585 197.217941,199.233307 201.468628,200.846130 205.623444,202.801071 209.746277,205.000397 213.805222,207.541809 217.768265,210.376495 221.667389,213.504395 225.470627,216.876678 229.177994,220.591064 232.789490,224.598709 236.273132,228.850708 239.628937,233.444839 242.856903,238.283325 245.957031,243.366180 248.929321,248.791153 251.709839,254.411621 254.362534,260.374207 256.791504,266.483398 258.996704,272.739227 261.010223,279.043915 262.768005,285.495270 264.302094,291.995453 265.644409,298.593384 266.731079,305.191315 267.625946,311.838104 268.297119,318.533813 268.744537,325.278351 269.000244,331.974030 269.032166,338.669739 268.872375,345.365448 268.488861,352.012238 267.913574,358.610168 267.114594,365.159241 266.123840,371.659424 264.941284,378.061890 263.567017,384.366577 261.969025,390.573547 260.211212,396.633850 258.229706,402.596436 256.056396,408.412384 253.723328,414.032837 251.166504,419.555603 248.449905,424.833923 245.509598,429.965668 242.409470,434.853027 239.149536,439.593750 235.697845,444.041260 232.054413,448.244385 228.219193,452.252045 224.288116,455.917542 220.261139,459.240967 216.170258,462.173401 212.015442,464.812561 207.828674,467.109589 203.577988,469.064545 199.263397,470.628510 194.948776,471.899200 190.634186,472.876678 186.255646,473.463196 181.909073,473.756439 177.562500,473.707550 173.215942,473.365448 168.869370,472.681213 164.586731,471.703735 160.304077,470.384155 156.085358,468.771332 151.898590,466.865265 147.807709,464.617065 143.748779,462.124512 139.753769,459.289856 135.854645,456.161926 132.051392,452.740753 128.344025,449.026367 124.764503,445.067596 121.280853,440.766724 117.893089,436.221466 114.665123,431.382996 111.565002,426.251282 108.624680,420.875153 105.812187,415.205811 103.191467,409.292114 "
|
||||
style="fill:url(#radialGradient37664-284-781);fill-opacity:1;stroke:#181818;stroke-width:0.6875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4"
|
||||
transform="matrix(0.3640721,-0.58678257,0.3795276,0.23777199,-128.13162,89.336986)" />
|
||||
<g
|
||||
id="Continents"
|
||||
inkscape:label="Continents"
|
||||
style="fill:url(#radialGradient1902-108-124);fill-opacity:1;fill-rule:evenodd"
|
||||
transform="matrix(0.67977314,0,0,0.68307417,-61.371653,-142.01634)">
|
||||
<polyline
|
||||
id="polyline1460"
|
||||
points="132.818436,384.610931 131.827682,384.953064 128.184235,388.227600 126.074867,388.667450 123.422180,385.441803 120.417938,385.832794 117.126053,389.107300 116.838409,393.896912 116.902328,400.641479 115.655891,409.292114 114.409447,415.352448 115.432167,418.235992 113.578484,420.386444 111.053642,420.924042 109.903076,422.732361 109.871117,423.172241 116.295090,433.728943 123.262383,443.161530 130.836914,451.421204 140.904327,460.071808 151.195465,466.425385 153.528549,464.470428 157.683365,463.248596 162.509323,463.688446 165.321808,463.835083 165.577484,459.387573 165.066132,457.628113 162.381485,454.793457 158.162750,448.244385 155.094604,442.526184 156.884354,433.680054 153.496597,425.664764 151.738800,419.017975 150.811951,410.220703 147.743790,405.479980 144.579727,397.953430 142.438416,395.851868 141.447662,389.058441 138.858887,386.419281 135.886597,384.855316 133.968994,384.219940 133.201950,380.994293 131.667877,376.351288 131.923553,370.926331 132.850403,369.069122 135.407196,368.140533 137.292847,366.625458 137.452652,362.911041 136.557755,358.316925 134.736038,353.967194 135.886597,352.158844 138.123810,351.914490 141.255890,349.812927 141.223938,346.245178 139.050644,343.557098 136.973236,343.654846 135.471115,341.602142 134.863876,337.643402 135.407196,330.947693 138.219681,327.575439 141.191971,325.571625 145.890106,326.158081 148.510818,330.361237 149.469635,333.635773 149.565506,336.421570 150.588226,338.327637 152.314072,339.891571 153.656403,344.045837 154.135788,348.737701 152.665634,353.771698 151.578995,357.730469 152.985229,359.587646 155.094604,356.557495 156.468872,353.234070 159.153519,351.572388 161.870132,351.474609 165.865143,353.967194 168.517807,355.237885 171.458130,352.696472 175.389221,351.425751 178.457397,351.621246 179.416199,352.940857 181.301834,352.403229 184.497833,352.452087 185.968002,353.918335 186.095840,356.704102 187.949539,357.143951 190.602203,359.392151 192.551788,361.004974 193.670380,358.610168 191.912582,355.482269 191.561020,353.576202 193.095093,351.767883 192.583740,349.030945 190.442413,347.906860 188.620697,346.147400 189.259888,345.169952 191.976501,346.049652 195.044662,348.835449 196.259140,351.230255 198.624191,353.771698 200.733551,353.282928 202.363510,350.057312 203.609955,343.996979 204.153275,334.710999 202.906830,330.752228 202.331558,328.406281 203.258408,324.594147 202.459396,316.676605 201.053146,314.819397 198.496353,317.311981 195.300339,320.781982 194.788971,323.567780 192.871368,323.518921 189.739288,325.669373 186.894852,327.477692 187.342285,323.470032 188.524796,319.755646 190.666138,317.311981 190.314575,313.450958 189.132050,308.123718 190.090851,304.898071 193.734299,301.965637 197.601471,302.063385 202.107834,303.773987 205.559525,305.875519 207.796722,306.217651 208.435928,302.698761 206.678116,300.548309 206.038925,296.980560 207.796722,294.585724 209.490601,292.581909 208.627686,290.529205 205.783249,292.386414 203.961517,291.555573 204.057388,289.258514 207.189484,286.130615 208.787491,282.953796 208.627686,279.532684 209.874130,275.427277 208.276123,272.152740 206.198730,271.273010 205.783249,275.231781 204.185242,277.479980 203.929565,281.927460 201.788239,283.393677 202.715073,269.513580 203.546036,261.938171 204.888351,257.050812 206.997711,254.998108 209.426682,251.283707 209.171005,248.595657 207.541046,244.734634 206.262650,243.708313 205.687363,241.362366 204.600723,239.211929 202.715073,239.798416 201.276871,239.896149 200.030426,234.959930 197.697342,233.395966 194.916824,233.884705 192.743546,234.715546 191.976501,231.929764 192.264130,228.068741 190.698090,230.903412 191.145538,235.986282 191.912582,241.362366 192.104340,246.347473 190.154770,250.208496 187.406204,253.238663 182.548279,255.780090 177.338791,257.979401 173.695343,260.911804 171.745789,262.866760 169.956009,265.603668 166.696106,264.919464 162.924805,265.066071 158.290604,266.092438 153.464630,269.220306 146.944778,274.352051 145.091095,277.479980 141.671371,283.442566 138.954773,288.036682 135.918564,293.950378 135.119568,298.593384 135.503082,301.476929 136.334045,297.420410 138.091858,294.048126 140.361008,290.871338 142.310577,287.987793 143.365265,289.502869 141.959015,292.190948 138.283615,298.055786 135.087601,306.071045 132.946274,309.492188 130.900833,310.176422 129.686356,314.330688 130.069870,319.755646 128.919312,329.628113 129.494598,334.515503 130.677109,341.797638 131.603958,350.546021 131.540024,355.482269 130.964752,360.565125 128.280106,366.772064 129.047150,373.125641 129.654404,377.084412 131.476105,380.456665 132.818436,384.610931 "
|
||||
style="fill:url(#radialGradient1904-972-786);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1464"
|
||||
points="144.579727,355.237885 146.497345,357.241699 147.583984,362.324585 148.638672,368.384918 149.980988,372.539154 150.364502,377.035553 148.798477,377.279877 146.753021,373.467743 146.976746,368.433777 146.593216,362.959930 144.579727,355.237885 "
|
||||
style="fill:url(#radialGradient1906-828-861);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1468"
|
||||
points="150.108826,378.892731 148.830429,379.870209 149.309830,383.584595 150.172745,386.614777 152.633667,390.964508 152.505829,386.565887 153.336792,386.077148 153.017197,383.780090 150.108826,378.892731 "
|
||||
style="fill:url(#radialGradient1908-502-115);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1472"
|
||||
points="201.181000,353.820557 200.797470,356.459747 200.413956,361.053864 199.966507,365.990082 199.007706,368.238281 196.866379,363.204285 197.921066,357.681580 199.103592,354.895782 201.181000,353.820557 "
|
||||
style="fill:url(#radialGradient1910-187-480);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1476"
|
||||
points="204.632675,320.342133 203.993469,316.774353 202.906830,312.668976 206.230682,314.575043 208.883362,312.277985 209.842163,309.052338 208.915314,303.822876 208.563766,299.961853 209.874130,294.487976 212.430923,295.514343 213.261887,299.570862 213.581497,305.386810 213.837173,310.958405 212.111328,314.917175 211.951538,317.018738 212.335052,321.466217 210.800964,325.913727 208.691605,325.376099 206.454407,326.646820 205.016205,324.203125 204.632675,320.342133 "
|
||||
style="fill:url(#radialGradient1912-38-980);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1480"
|
||||
points="213.773254,334.955322 213.709335,340.820160 213.869125,343.263885 216.362015,346.636139 219.526062,350.594910 218.695099,344.632324 219.685867,341.406677 222.722061,339.060730 227.835663,334.662109 230.648163,335.786194 233.332809,333.147003 234.355515,326.011475 234.675125,319.218048 233.556534,312.522369 233.588486,306.071045 231.511078,300.646057 228.890350,297.420410 226.365509,296.980560 225.246902,294.830109 226.365509,293.461639 225.023193,290.235992 222.338547,287.401337 220.964264,289.698364 217.352783,290.675842 216.330063,294.292480 216.362015,299.375336 220.644653,297.469269 222.754028,297.958038 220.708588,301.623535 219.941544,306.852997 220.293106,310.714020 219.845657,317.654083 219.078629,323.909912 214.955765,329.237122 215.083618,333.000397 213.773254,334.955322 "
|
||||
style="fill:url(#radialGradient1914-119-179);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1484"
|
||||
points="232.533813,338.767487 230.200729,341.748779 229.401718,344.436798 229.721313,347.662476 233.460648,348.542206 237.040161,346.929382 237.231934,342.872864 235.378250,340.478088 233.620453,340.282562 232.533813,338.767487 "
|
||||
style="fill:url(#radialGradient1916-825-422);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1488"
|
||||
points="264.877380,375.813690 262.991730,379.919098 260.371002,382.167236 258.645172,385.148529 258.645172,389.693817 256.887360,391.062256 255.161514,388.911804 254.522308,386.956848 252.732559,385.197418 253.339798,391.697632 251.709839,392.332977 249.792236,387.738861 248.322067,389.840393 246.724060,393.017212 244.327072,395.412018 242.952774,399.664001 241.514587,403.329529 241.067139,407.337158 239.565018,407.190552 238.318573,407.777039 235.665894,409.096649 233.173004,407.679291 233.141052,401.570068 234.707092,399.712891 235.122574,395.705231 237.231934,393.652588 239.692856,394.434540 241.834183,392.039734 240.843414,387.152374 239.980499,385.099670 240.907349,382.265015 244.550781,379.332581 247.043671,372.685760 247.139542,368.384918 249.121078,365.110352 252.125320,361.151611 254.202728,353.967194 256.503845,350.399414 255.992477,346.684998 255.864655,342.335266 255.832672,339.744965 254.586243,339.353973 254.074875,342.139771 251.581985,340.722412 252.189240,343.654846 251.997467,347.760223 251.294357,352.647583 251.486115,357.632721 248.897354,354.993530 246.915833,355.335632 246.020950,351.670135 245.733307,346.489502 247.778748,340.233704 248.002472,336.763672 247.586990,329.774750 247.299347,324.545258 248.705597,319.315765 251.230438,321.319580 254.234680,326.451324 255.608963,324.154266 255.097595,321.417358 253.915070,321.612854 252.253159,317.702942 254.202728,316.774353 253.883118,313.548676 254.714081,310.469666 254.746033,303.969452 255.001724,293.999268 253.947052,293.070679 252.349030,292.777405 250.495346,290.382599 250.303589,287.938934 249.312836,284.077911 247.235428,279.679291 245.381744,278.261963 242.920822,273.912201 241.546539,269.122559 241.035172,265.408173 242.345535,263.502106 240.555771,258.761383 238.734055,257.979401 236.560776,253.336411 234.131805,249.573120 232.501846,251.185959 230.648163,249.768631 228.315079,245.272247 226.653152,244.343658 225.438675,246.494095 223.808701,245.174515 220.964264,239.896149 219.430176,240.775894 217.672379,242.193222 216.170258,241.069122 212.718582,239.945023 210.257645,239.114182 207.509079,237.647964 205.527557,234.422318 206.805954,234.471191 209.362778,234.520065 210.225693,233.004974 208.979248,230.072571 209.810211,226.993515 210.737045,224.109970 213.325806,224.794220 215.722824,225.967178 216.745544,227.873245 219.781738,227.531128 222.114822,224.549835 224.032425,226.553665 226.844925,229.241714 229.785248,226.700287 230.136795,223.425751 229.721313,220.933197 236.592728,229.290573 241.898102,236.768250 246.564270,244.490280 251.837677,254.704865 255.960541,264.332947 260.115326,276.258118 264.302094,291.995453 267.210449,308.514740 268.393005,320.537628 269.000244,333.538025 268.840424,345.169952 268.201202,356.557495 266.794983,367.358551 265.516571,374.933960 264.877380,375.813690 "
|
||||
style="fill:url(#radialGradient1918-387-755);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1492"
|
||||
points="244.774506,357.779327 243.304337,356.313110 242.345535,358.512421 241.131058,362.666687 239.916580,364.817108 238.062897,367.945038 237.615448,372.930145 238.414459,375.324951 239.373245,373.125641 239.852661,368.727020 240.683624,367.602905 241.067139,371.121826 241.290848,375.129456 241.834183,378.452850 243.336304,376.986664 243.528061,376.937775 243.719818,376.888916 243.911591,376.791168 244.071396,376.644531 244.390976,376.351288 244.678635,376.009186 244.934311,375.618195 245.126068,375.324951 245.221939,375.129456 245.285858,375.031708 245.253906,372.490265 244.486862,365.159241 244.199219,361.884705 244.774506,357.779327 "
|
||||
style="fill:url(#radialGradient1920-264-381);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
<polyline
|
||||
id="polyline1496"
|
||||
points="262.192749,389.449432 260.115326,391.160004 258.261658,394.287933 256.663635,394.532288 255.992477,392.968323 255.065643,395.802979 253.851151,400.885864 250.783005,404.209290 250.175766,401.276855 249.344803,399.810638 245.573502,402.889679 242.537292,406.213104 240.747543,406.995056 238.126801,409.878601 236.049423,409.976349 233.748291,411.002716 231.606964,415.010315 228.986237,420.826294 226.333542,423.123352 220.996231,428.059601 216.617691,433.680054 213.485611,439.349396 210.385483,446.582703 209.171005,453.278381 210.353516,458.605591 214.220703,458.654480 216.777496,458.752228 218.535294,460.560547 223.648911,456.504028 228.187241,452.252045 232.693619,447.511292 237.775253,441.402100 243.400223,433.386810 247.906586,425.811401 251.677872,418.529236 255.161514,410.611694 258.069885,403.134064 260.690613,394.923279 262.192749,389.449432 "
|
||||
style="fill:url(#radialGradient20143-627-23);stroke:#181818;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 40 KiB |
@@ -1,602 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/bill/Dropbox/src/wsjtx-dev/icons/windows-icons/icon_1024x1024.png"
|
||||
version="1.1"
|
||||
width="1024"
|
||||
sodipodi:version="0.32"
|
||||
sodipodi:docname="wsjtx_globe_1024x1024.svg"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
id="svg1432"
|
||||
height="1024">
|
||||
<sodipodi:namedview
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
id="base"
|
||||
inkscape:current-layer="svg1432"
|
||||
inkscape:cx="512"
|
||||
inkscape:cy="512"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-height="858"
|
||||
inkscape:window-width="1114"
|
||||
inkscape:window-x="72"
|
||||
inkscape:window-y="31"
|
||||
inkscape:zoom="0.69433594"
|
||||
pagecolor="#ffffff"
|
||||
showborder="true"
|
||||
showguides="true"
|
||||
showgrid="false"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:showpageshadow="false" />
|
||||
<metadata
|
||||
id="metadata3060">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title />
|
||||
<dc:description>Simple globe centered on North America</dc:description>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>earth globe northamerica</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:publisher>
|
||||
<cc:Agent
|
||||
rdf:about="http://www.openclipart.org/">
|
||||
<dc:title>Open Clip Art Library</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Dan Gerhrads</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>Dan Gerhrads</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:date>May 1, 2005</dc:date>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<cc:license
|
||||
rdf:resource="http://web.resource.org/cc/PublicDomain" />
|
||||
<dc:language>en</dc:language>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://web.resource.org/cc/PublicDomain">
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs1759">
|
||||
<linearGradient
|
||||
id="linearGradient37658">
|
||||
<stop
|
||||
style="stop-color:#2f7aff;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop37660" />
|
||||
<stop
|
||||
style="stop-color:#0000b3;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop37662" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient20137">
|
||||
<stop
|
||||
style="stop-color:#00bf00;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop20139" />
|
||||
<stop
|
||||
style="stop-color:#007500;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop20141" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient20143"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient37658"
|
||||
r="112.3373"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient37664"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.806632,1.239722)"
|
||||
fy="270.08731"
|
||||
fx="221.61394"
|
||||
cy="270.08731"
|
||||
cx="221.61394" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1902"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1904"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1906"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1908"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1910"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1912"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1914"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1916"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1918"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1920"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient37658-427"
|
||||
r="112.3373"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient37664-403"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.806632,1.239722)"
|
||||
fy="270.08731"
|
||||
fx="221.61394"
|
||||
cy="270.08731"
|
||||
cx="221.61394" />
|
||||
<linearGradient
|
||||
id="linearGradient37658-427">
|
||||
<stop
|
||||
style="stop-color:#488afe;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7178" />
|
||||
<stop
|
||||
style="stop-color:#0000cc;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7180" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-396"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1902-893"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-396">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7184" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7186" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-527"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1904-666"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-527">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7190" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7192" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-774"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1906-717"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-774">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7196" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7198" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-253"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1908-922"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-253">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7202" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7204" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-972"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1910-261"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-972">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7208" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7210" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-945"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1912-713"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-945">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7214" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7216" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-600"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1914-146"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-600">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7220" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7222" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-196"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1916-817"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-196">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7226" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7228" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-388"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1918-23"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-388">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7232" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7234" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-202"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient1920-260"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-202">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7238" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7240" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient20137-151"
|
||||
r="188.61865"
|
||||
inkscape:collect="always"
|
||||
id="radialGradient20143-884"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="scale(0.893959,1.11862)"
|
||||
fy="298.37747"
|
||||
fx="205.17723"
|
||||
cy="297.1124"
|
||||
cx="202.06305" />
|
||||
<linearGradient
|
||||
id="linearGradient20137-151">
|
||||
<stop
|
||||
style="stop-color:#00d800;stop-opacity:1.0000000;"
|
||||
offset="0.0000000"
|
||||
id="stop7244" />
|
||||
<stop
|
||||
style="stop-color:#008e00;stop-opacity:1.0000000;"
|
||||
offset="1.0000000"
|
||||
id="stop7246" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<desc
|
||||
id="desc1434">wmf2svg</desc>
|
||||
<polyline
|
||||
transform="matrix(2.2285926,-3.5745108,2.3232002,1.4484387,-677.00545,692.67468)"
|
||||
style="fill:url(#radialGradient37664-403);fill-opacity:1;stroke:#0c0c0c;stroke-width:0.6875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4"
|
||||
points="103.191467,409.292114 100.730545,403.134064 98.525299,396.927094 96.543777,390.573547 94.785973,384.171082 93.219925,377.622009 91.909569,371.072968 90.790962,364.426147 89.928040,357.779327 89.256882,351.083649 88.777481,344.387970 88.521805,337.692261 88.489838,330.947693 88.681602,324.300873 89.033165,317.605194 89.640404,311.007263 90.407448,304.458221 91.398209,298.006897 92.580727,291.604431 93.986977,285.299744 95.553017,279.092804 97.342781,272.983582 99.324303,267.069916 101.465622,261.253937 103.830666,255.584595 106.387474,250.110733 109.104080,244.783508 112.012444,239.700668 115.112572,234.764420 118.404449,230.072571 121.856140,225.625061 125.499588,221.373062 129.302826,217.414291 133.265884,213.748779 137.260895,210.425354 141.351776,207.444077 145.506577,204.804901 149.725311,202.556717 153.975983,200.601776 158.258652,198.988937 162.573242,197.718231 166.919815,196.789627 171.266373,196.154266 175.644897,195.909912 179.991470,195.909912 184.338043,196.300888 188.652649,196.985123 192.967270,197.962585 197.217941,199.233307 201.468628,200.846130 205.623444,202.801071 209.746277,205.000397 213.805222,207.541809 217.768265,210.376495 221.667389,213.504395 225.470627,216.876678 229.177994,220.591064 232.789490,224.598709 236.273132,228.850708 239.628937,233.444839 242.856903,238.283325 245.957031,243.366180 248.929321,248.791153 251.709839,254.411621 254.362534,260.374207 256.791504,266.483398 258.996704,272.739227 261.010223,279.043915 262.768005,285.495270 264.302094,291.995453 265.644409,298.593384 266.731079,305.191315 267.625946,311.838104 268.297119,318.533813 268.744537,325.278351 269.000244,331.974030 269.032166,338.669739 268.872375,345.365448 268.488861,352.012238 267.913574,358.610168 267.114594,365.159241 266.123840,371.659424 264.941284,378.061890 263.567017,384.366577 261.969025,390.573547 260.211212,396.633850 258.229706,402.596436 256.056396,408.412384 253.723328,414.032837 251.166504,419.555603 248.449905,424.833923 245.509598,429.965668 242.409470,434.853027 239.149536,439.593750 235.697845,444.041260 232.054413,448.244385 228.219193,452.252045 224.288116,455.917542 220.261139,459.240967 216.170258,462.173401 212.015442,464.812561 207.828674,467.109589 203.577988,469.064545 199.263397,470.628510 194.948776,471.899200 190.634186,472.876678 186.255646,473.463196 181.909073,473.756439 177.562500,473.707550 173.215942,473.365448 168.869370,472.681213 164.586731,471.703735 160.304077,470.384155 156.085358,468.771332 151.898590,466.865265 147.807709,464.617065 143.748779,462.124512 139.753769,459.289856 135.854645,456.161926 132.051392,452.740753 128.344025,449.026367 124.764503,445.067596 121.280853,440.766724 117.893089,436.221466 114.665123,431.382996 111.565002,426.251282 108.624680,420.875153 105.812187,415.205811 103.191467,409.292114 "
|
||||
id="polyline1560" />
|
||||
<g
|
||||
transform="matrix(4.1610916,0,0,4.1610916,-268.34786,-716.6628)"
|
||||
style="fill:url(#radialGradient1902-893);fill-opacity:1;fill-rule:evenodd"
|
||||
inkscape:label="Continents"
|
||||
id="Continents">
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1904-666);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="132.818436,384.610931 131.827682,384.953064 128.184235,388.227600 126.074867,388.667450 123.422180,385.441803 120.417938,385.832794 117.126053,389.107300 116.838409,393.896912 116.902328,400.641479 115.655891,409.292114 114.409447,415.352448 115.432167,418.235992 113.578484,420.386444 111.053642,420.924042 109.903076,422.732361 109.871117,423.172241 116.295090,433.728943 123.262383,443.161530 130.836914,451.421204 140.904327,460.071808 151.195465,466.425385 153.528549,464.470428 157.683365,463.248596 162.509323,463.688446 165.321808,463.835083 165.577484,459.387573 165.066132,457.628113 162.381485,454.793457 158.162750,448.244385 155.094604,442.526184 156.884354,433.680054 153.496597,425.664764 151.738800,419.017975 150.811951,410.220703 147.743790,405.479980 144.579727,397.953430 142.438416,395.851868 141.447662,389.058441 138.858887,386.419281 135.886597,384.855316 133.968994,384.219940 133.201950,380.994293 131.667877,376.351288 131.923553,370.926331 132.850403,369.069122 135.407196,368.140533 137.292847,366.625458 137.452652,362.911041 136.557755,358.316925 134.736038,353.967194 135.886597,352.158844 138.123810,351.914490 141.255890,349.812927 141.223938,346.245178 139.050644,343.557098 136.973236,343.654846 135.471115,341.602142 134.863876,337.643402 135.407196,330.947693 138.219681,327.575439 141.191971,325.571625 145.890106,326.158081 148.510818,330.361237 149.469635,333.635773 149.565506,336.421570 150.588226,338.327637 152.314072,339.891571 153.656403,344.045837 154.135788,348.737701 152.665634,353.771698 151.578995,357.730469 152.985229,359.587646 155.094604,356.557495 156.468872,353.234070 159.153519,351.572388 161.870132,351.474609 165.865143,353.967194 168.517807,355.237885 171.458130,352.696472 175.389221,351.425751 178.457397,351.621246 179.416199,352.940857 181.301834,352.403229 184.497833,352.452087 185.968002,353.918335 186.095840,356.704102 187.949539,357.143951 190.602203,359.392151 192.551788,361.004974 193.670380,358.610168 191.912582,355.482269 191.561020,353.576202 193.095093,351.767883 192.583740,349.030945 190.442413,347.906860 188.620697,346.147400 189.259888,345.169952 191.976501,346.049652 195.044662,348.835449 196.259140,351.230255 198.624191,353.771698 200.733551,353.282928 202.363510,350.057312 203.609955,343.996979 204.153275,334.710999 202.906830,330.752228 202.331558,328.406281 203.258408,324.594147 202.459396,316.676605 201.053146,314.819397 198.496353,317.311981 195.300339,320.781982 194.788971,323.567780 192.871368,323.518921 189.739288,325.669373 186.894852,327.477692 187.342285,323.470032 188.524796,319.755646 190.666138,317.311981 190.314575,313.450958 189.132050,308.123718 190.090851,304.898071 193.734299,301.965637 197.601471,302.063385 202.107834,303.773987 205.559525,305.875519 207.796722,306.217651 208.435928,302.698761 206.678116,300.548309 206.038925,296.980560 207.796722,294.585724 209.490601,292.581909 208.627686,290.529205 205.783249,292.386414 203.961517,291.555573 204.057388,289.258514 207.189484,286.130615 208.787491,282.953796 208.627686,279.532684 209.874130,275.427277 208.276123,272.152740 206.198730,271.273010 205.783249,275.231781 204.185242,277.479980 203.929565,281.927460 201.788239,283.393677 202.715073,269.513580 203.546036,261.938171 204.888351,257.050812 206.997711,254.998108 209.426682,251.283707 209.171005,248.595657 207.541046,244.734634 206.262650,243.708313 205.687363,241.362366 204.600723,239.211929 202.715073,239.798416 201.276871,239.896149 200.030426,234.959930 197.697342,233.395966 194.916824,233.884705 192.743546,234.715546 191.976501,231.929764 192.264130,228.068741 190.698090,230.903412 191.145538,235.986282 191.912582,241.362366 192.104340,246.347473 190.154770,250.208496 187.406204,253.238663 182.548279,255.780090 177.338791,257.979401 173.695343,260.911804 171.745789,262.866760 169.956009,265.603668 166.696106,264.919464 162.924805,265.066071 158.290604,266.092438 153.464630,269.220306 146.944778,274.352051 145.091095,277.479980 141.671371,283.442566 138.954773,288.036682 135.918564,293.950378 135.119568,298.593384 135.503082,301.476929 136.334045,297.420410 138.091858,294.048126 140.361008,290.871338 142.310577,287.987793 143.365265,289.502869 141.959015,292.190948 138.283615,298.055786 135.087601,306.071045 132.946274,309.492188 130.900833,310.176422 129.686356,314.330688 130.069870,319.755646 128.919312,329.628113 129.494598,334.515503 130.677109,341.797638 131.603958,350.546021 131.540024,355.482269 130.964752,360.565125 128.280106,366.772064 129.047150,373.125641 129.654404,377.084412 131.476105,380.456665 132.818436,384.610931 "
|
||||
id="polyline1460" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1906-717);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="144.579727,355.237885 146.497345,357.241699 147.583984,362.324585 148.638672,368.384918 149.980988,372.539154 150.364502,377.035553 148.798477,377.279877 146.753021,373.467743 146.976746,368.433777 146.593216,362.959930 144.579727,355.237885 "
|
||||
id="polyline1464" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1908-922);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="150.108826,378.892731 148.830429,379.870209 149.309830,383.584595 150.172745,386.614777 152.633667,390.964508 152.505829,386.565887 153.336792,386.077148 153.017197,383.780090 150.108826,378.892731 "
|
||||
id="polyline1468" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1910-261);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="201.181000,353.820557 200.797470,356.459747 200.413956,361.053864 199.966507,365.990082 199.007706,368.238281 196.866379,363.204285 197.921066,357.681580 199.103592,354.895782 201.181000,353.820557 "
|
||||
id="polyline1472" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1912-713);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="204.632675,320.342133 203.993469,316.774353 202.906830,312.668976 206.230682,314.575043 208.883362,312.277985 209.842163,309.052338 208.915314,303.822876 208.563766,299.961853 209.874130,294.487976 212.430923,295.514343 213.261887,299.570862 213.581497,305.386810 213.837173,310.958405 212.111328,314.917175 211.951538,317.018738 212.335052,321.466217 210.800964,325.913727 208.691605,325.376099 206.454407,326.646820 205.016205,324.203125 204.632675,320.342133 "
|
||||
id="polyline1476" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1914-146);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="213.773254,334.955322 213.709335,340.820160 213.869125,343.263885 216.362015,346.636139 219.526062,350.594910 218.695099,344.632324 219.685867,341.406677 222.722061,339.060730 227.835663,334.662109 230.648163,335.786194 233.332809,333.147003 234.355515,326.011475 234.675125,319.218048 233.556534,312.522369 233.588486,306.071045 231.511078,300.646057 228.890350,297.420410 226.365509,296.980560 225.246902,294.830109 226.365509,293.461639 225.023193,290.235992 222.338547,287.401337 220.964264,289.698364 217.352783,290.675842 216.330063,294.292480 216.362015,299.375336 220.644653,297.469269 222.754028,297.958038 220.708588,301.623535 219.941544,306.852997 220.293106,310.714020 219.845657,317.654083 219.078629,323.909912 214.955765,329.237122 215.083618,333.000397 213.773254,334.955322 "
|
||||
id="polyline1480" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1916-817);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="232.533813,338.767487 230.200729,341.748779 229.401718,344.436798 229.721313,347.662476 233.460648,348.542206 237.040161,346.929382 237.231934,342.872864 235.378250,340.478088 233.620453,340.282562 232.533813,338.767487 "
|
||||
id="polyline1484" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1918-23);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="264.877380,375.813690 262.991730,379.919098 260.371002,382.167236 258.645172,385.148529 258.645172,389.693817 256.887360,391.062256 255.161514,388.911804 254.522308,386.956848 252.732559,385.197418 253.339798,391.697632 251.709839,392.332977 249.792236,387.738861 248.322067,389.840393 246.724060,393.017212 244.327072,395.412018 242.952774,399.664001 241.514587,403.329529 241.067139,407.337158 239.565018,407.190552 238.318573,407.777039 235.665894,409.096649 233.173004,407.679291 233.141052,401.570068 234.707092,399.712891 235.122574,395.705231 237.231934,393.652588 239.692856,394.434540 241.834183,392.039734 240.843414,387.152374 239.980499,385.099670 240.907349,382.265015 244.550781,379.332581 247.043671,372.685760 247.139542,368.384918 249.121078,365.110352 252.125320,361.151611 254.202728,353.967194 256.503845,350.399414 255.992477,346.684998 255.864655,342.335266 255.832672,339.744965 254.586243,339.353973 254.074875,342.139771 251.581985,340.722412 252.189240,343.654846 251.997467,347.760223 251.294357,352.647583 251.486115,357.632721 248.897354,354.993530 246.915833,355.335632 246.020950,351.670135 245.733307,346.489502 247.778748,340.233704 248.002472,336.763672 247.586990,329.774750 247.299347,324.545258 248.705597,319.315765 251.230438,321.319580 254.234680,326.451324 255.608963,324.154266 255.097595,321.417358 253.915070,321.612854 252.253159,317.702942 254.202728,316.774353 253.883118,313.548676 254.714081,310.469666 254.746033,303.969452 255.001724,293.999268 253.947052,293.070679 252.349030,292.777405 250.495346,290.382599 250.303589,287.938934 249.312836,284.077911 247.235428,279.679291 245.381744,278.261963 242.920822,273.912201 241.546539,269.122559 241.035172,265.408173 242.345535,263.502106 240.555771,258.761383 238.734055,257.979401 236.560776,253.336411 234.131805,249.573120 232.501846,251.185959 230.648163,249.768631 228.315079,245.272247 226.653152,244.343658 225.438675,246.494095 223.808701,245.174515 220.964264,239.896149 219.430176,240.775894 217.672379,242.193222 216.170258,241.069122 212.718582,239.945023 210.257645,239.114182 207.509079,237.647964 205.527557,234.422318 206.805954,234.471191 209.362778,234.520065 210.225693,233.004974 208.979248,230.072571 209.810211,226.993515 210.737045,224.109970 213.325806,224.794220 215.722824,225.967178 216.745544,227.873245 219.781738,227.531128 222.114822,224.549835 224.032425,226.553665 226.844925,229.241714 229.785248,226.700287 230.136795,223.425751 229.721313,220.933197 236.592728,229.290573 241.898102,236.768250 246.564270,244.490280 251.837677,254.704865 255.960541,264.332947 260.115326,276.258118 264.302094,291.995453 267.210449,308.514740 268.393005,320.537628 269.000244,333.538025 268.840424,345.169952 268.201202,356.557495 266.794983,367.358551 265.516571,374.933960 264.877380,375.813690 "
|
||||
id="polyline1488" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient1920-260);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="244.774506,357.779327 243.304337,356.313110 242.345535,358.512421 241.131058,362.666687 239.916580,364.817108 238.062897,367.945038 237.615448,372.930145 238.414459,375.324951 239.373245,373.125641 239.852661,368.727020 240.683624,367.602905 241.067139,371.121826 241.290848,375.129456 241.834183,378.452850 243.336304,376.986664 243.528061,376.937775 243.719818,376.888916 243.911591,376.791168 244.071396,376.644531 244.390976,376.351288 244.678635,376.009186 244.934311,375.618195 245.126068,375.324951 245.221939,375.129456 245.285858,375.031708 245.253906,372.490265 244.486862,365.159241 244.199219,361.884705 244.774506,357.779327 "
|
||||
id="polyline1492" />
|
||||
<polyline
|
||||
transform="matrix(0.535579,-0.859032,0.558315,0.348091,-98.20917,338.6942)"
|
||||
style="fill:url(#radialGradient20143-884);stroke:#0c0c0c;stroke-width:0.444585;stroke-linecap:round;stroke-linejoin:round"
|
||||
points="262.192749,389.449432 260.115326,391.160004 258.261658,394.287933 256.663635,394.532288 255.992477,392.968323 255.065643,395.802979 253.851151,400.885864 250.783005,404.209290 250.175766,401.276855 249.344803,399.810638 245.573502,402.889679 242.537292,406.213104 240.747543,406.995056 238.126801,409.878601 236.049423,409.976349 233.748291,411.002716 231.606964,415.010315 228.986237,420.826294 226.333542,423.123352 220.996231,428.059601 216.617691,433.680054 213.485611,439.349396 210.385483,446.582703 209.171005,453.278381 210.353516,458.605591 214.220703,458.654480 216.777496,458.752228 218.535294,460.560547 223.648911,456.504028 228.187241,452.252045 232.693619,447.511292 237.775253,441.402100 243.400223,433.386810 247.906586,425.811401 251.677872,418.529236 255.161514,410.611694 258.069885,403.134064 260.690613,394.923279 262.192749,389.449432 "
|
||||
id="polyline1496" />
|
||||
</g>
|
||||
<text
|
||||
transform="matrix(0.98267844,-0.18531886,0.18531886,0.98267844,0,0)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3096"
|
||||
y="456.47293"
|
||||
x="394.15689"
|
||||
style="font-size:187.56237793000002512px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ff8119;fill-opacity:0.77168947;stroke:none;font-family:Purisa;-inkscape-font-specification:Purisa Bold"
|
||||
xml:space="preserve"><tspan
|
||||
dy="-109.78781"
|
||||
dx="0 -9.8032694 -11.763925 -17.645885"
|
||||
id="tspan3102"
|
||||
y="456.47293"
|
||||
x="394.15692"
|
||||
sodipodi:role="line">WSJT-X</tspan><tspan
|
||||
dx="0 -17.645885 -23.527849 -13.724579 29.30662 29.30662 -17.645885 -23.527849"
|
||||
id="tspan3874"
|
||||
y="690.92584"
|
||||
x="394.15689"
|
||||
sodipodi:role="line">JT65&JT9</tspan><tspan
|
||||
dy="91.489815"
|
||||
dx="0 0 0 0 -17.645885 -5.8819623 -17.645885"
|
||||
id="tspan3100"
|
||||
y="925.37885"
|
||||
x="394.15689"
|
||||
sodipodi:role="line">by K1JT</tspan></text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 33 KiB |
@@ -61,9 +61,9 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
tryUnpack();
|
||||
}
|
||||
|
||||
DecodedText::DecodedText (QString const& ft8callmessage):
|
||||
DecodedText::DecodedText (QString const& js8callmessage):
|
||||
frameType_(Varicode::FrameUnknown),
|
||||
message_(ft8callmessage),
|
||||
message_(js8callmessage),
|
||||
isBeacon_(false),
|
||||
isAlt_(false)
|
||||
{
|
||||
@@ -108,7 +108,8 @@ bool DecodedText::tryUnpackBeacon(){
|
||||
|
||||
bool isAlt = false;
|
||||
quint8 type = Varicode::FrameUnknown;
|
||||
QStringList parts = Varicode::unpackBeaconMessage(m, &type, &isAlt);
|
||||
quint8 bits3 = 0;
|
||||
QStringList parts = Varicode::unpackBeaconMessage(m, &type, &isAlt, &bits3);
|
||||
|
||||
if(parts.isEmpty() || parts.length() < 2){
|
||||
return false;
|
||||
@@ -130,7 +131,7 @@ bool DecodedText::tryUnpackBeacon(){
|
||||
cmp.append(parts.at(1));
|
||||
}
|
||||
compound_ = cmp.join("/");
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? "CQCQCQ" : "BEACON").arg(extra_);
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : "BEACON").arg(extra_);
|
||||
frameType_ = type;
|
||||
return true;
|
||||
}
|
||||
@@ -143,7 +144,8 @@ bool DecodedText::tryUnpackCompound(){
|
||||
}
|
||||
|
||||
quint8 type = Varicode::FrameUnknown;
|
||||
auto parts = Varicode::unpackCompoundMessage(m, &type);
|
||||
quint8 bits3 = 0;
|
||||
auto parts = Varicode::unpackCompoundMessage(m, &type, &bits3);
|
||||
if(parts.isEmpty() || parts.length() < 2){
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class DecodedText
|
||||
{
|
||||
public:
|
||||
explicit DecodedText (QString const& message, bool, QString const& my_grid);
|
||||
explicit DecodedText (QString const& ft8callmessage);
|
||||
explicit DecodedText (QString const& js8callmessage);
|
||||
|
||||
bool tryUnpack();
|
||||
bool tryUnpackBeacon();
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
|
||||
#include "DriftingDateTime.h"
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
|
||||
#include "moc_displaytext.cpp"
|
||||
@@ -288,13 +290,13 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
|
||||
t2.sprintf("%4d",txFreq);
|
||||
QString t;
|
||||
if(bFastMode or modeTx=="FT8") {
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \
|
||||
t = DriftingDateTime::currentDateTimeUtc().toString("hhmmss") + \
|
||||
" Tx " + t2 + t1 + text;
|
||||
} else if(modeTx.mid(0,6)=="FT8fox") {
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \
|
||||
t = DriftingDateTime::currentDateTimeUtc().toString("hhmmss") + \
|
||||
" Tx" + modeTx.mid(7) + " " + text;
|
||||
} else {
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmm") + \
|
||||
t = DriftingDateTime::currentDateTimeUtc().toString("hhmm") + \
|
||||
" Tx " + t2 + t1 + text;
|
||||
}
|
||||
appendText (t, color_ReceivedMsg);
|
||||
@@ -302,7 +304,7 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
|
||||
|
||||
void DisplayText::displayQSY(QString text)
|
||||
{
|
||||
QString t = QDateTime::currentDateTimeUtc().toString("hhmmss") + " " + text;
|
||||
QString t = DriftingDateTime::currentDateTimeUtc().toString("hhmmss") + " " + text;
|
||||
appendText (t, "hotpink");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
set (LANGUAGES
|
||||
en
|
||||
)
|
||||
|
||||
set (common_SRCS
|
||||
common/communication.adoc
|
||||
common/license.adoc
|
||||
common/links.adoc
|
||||
)
|
||||
|
||||
set (UG_SRCS
|
||||
docinfo.html
|
||||
docinfo.xml
|
||||
acknowledgements.adoc
|
||||
astro_data.adoc
|
||||
config-details.adoc
|
||||
controls-functions-center.adoc
|
||||
controls-functions-left.adoc
|
||||
controls-functions-main-window.adoc
|
||||
controls-functions-menus.adoc
|
||||
controls-functions-messages.adoc
|
||||
controls-functions-status-bar.adoc
|
||||
controls-functions-wide-graph.adoc
|
||||
cooperating-programs.adoc
|
||||
decoder_notes.adoc
|
||||
faq.adoc
|
||||
font-sizes.adoc
|
||||
install-from-source.adoc
|
||||
install-linux.adoc
|
||||
install-mac.adoc
|
||||
install-windows.adoc
|
||||
introduction.adoc
|
||||
measurement_tools.adoc
|
||||
protocols.adoc
|
||||
logging.adoc
|
||||
make-qso.adoc
|
||||
measurement_tools.adoc
|
||||
new_features.adoc
|
||||
platform-dependencies.adoc
|
||||
protocols.adoc
|
||||
settings-advanced.adoc
|
||||
settings-audio.adoc
|
||||
settings-colors.adoc
|
||||
settings-frequencies.adoc
|
||||
settings-general.adoc
|
||||
settings-radio.adoc
|
||||
settings-reporting.adoc
|
||||
settings-txmacros.adoc
|
||||
support.adoc
|
||||
system-requirements.adoc
|
||||
transceiver-setup.adoc
|
||||
tutorial-example1.adoc
|
||||
tutorial-example2.adoc
|
||||
tutorial-example3.adoc
|
||||
tutorial-main-window.adoc
|
||||
tutorial-wide-graph-settings.adoc
|
||||
utilities.adoc
|
||||
vhf-features.adoc
|
||||
wsjtx-main.adoc
|
||||
wspr.adoc
|
||||
)
|
||||
|
||||
set (UG_IMGS
|
||||
images/130610_2343-wav-80.png
|
||||
images/170709_135615.wav.png
|
||||
images/AstroData_2.png
|
||||
images/Astronomical_data.png
|
||||
images/auto-seq.png
|
||||
images/band-settings.png
|
||||
images/colors.png
|
||||
images/config-menu.png
|
||||
images/decode-menu.png
|
||||
images/decodes.png
|
||||
images/download_samples.png
|
||||
images/echo_144.png
|
||||
images/file-menu.png
|
||||
images/FreqCal.png
|
||||
images/FreqCal_Graph.png
|
||||
images/FreqCal_Results.png
|
||||
images/freemsg.png
|
||||
images/ft8_decodes.png
|
||||
images/help-menu.png
|
||||
images/JT4F.png
|
||||
images/JT65B.png
|
||||
images/keyboard-shortcuts.png
|
||||
images/MSK144.png
|
||||
images/QRA64.png
|
||||
images/WSPR_WideGraphControls.png
|
||||
images/WSPR_1a.png
|
||||
images/WSPR_2.png
|
||||
images/jtalert.png
|
||||
images/keyboard-shortcuts.png
|
||||
images/log-qso.png
|
||||
images/MacAppMenu.png
|
||||
images/main-ui.png
|
||||
images/main-ui-controls.png
|
||||
images/misc-controls-center.png
|
||||
images/misc-main-ui.png
|
||||
images/mode-menu.png
|
||||
images/new-msg-box.png
|
||||
images/psk-reporter.png
|
||||
images/r3666-config-screen-80.png
|
||||
images/r3666-main-ui-80.png
|
||||
images/r4148-txmac-ui.png
|
||||
images/RadioTab.png
|
||||
images/reporting.png
|
||||
images/save-menu.png
|
||||
images/settings-advanced.png
|
||||
images/settings-audio.png
|
||||
images/settings-frequencies.png
|
||||
images/settings-general.png
|
||||
images/setup-menu.png
|
||||
images/special-mouse-commands.png
|
||||
images/status-bar-a.png
|
||||
images/tools-menu.png
|
||||
images/traditional-msg-box.png
|
||||
images/tx-macros.png
|
||||
images/VHF_controls.png
|
||||
images/view-menu.png
|
||||
images/wide-graph-controls.png
|
||||
|
||||
)
|
||||
|
||||
find_program (ASCIIDOCTOR_EXECUTABLE NAMES asciidoctor)
|
||||
if (NOT ASCIIDOCTOR_EXECUTABLE)
|
||||
message (FATAL_ERROR "asciidoctor is required to build the documentation
|
||||
|
||||
Building the documenation may optionally be turned off by setting the CMake
|
||||
option WSJT_GENERATE_DOCS to OFF.")
|
||||
endif (NOT ASCIIDOCTOR_EXECUTABLE)
|
||||
|
||||
find_program (FOPUB_EXECUTABLE NAMES fopub)
|
||||
|
||||
include (CMakeParseArguments)
|
||||
|
||||
# generate a document from asciidoc text files(s)
|
||||
#
|
||||
# HTML - generate an HTML document
|
||||
# PDF - generate a PDF document
|
||||
# SOURCE - top level asciidoc file
|
||||
# ASCIIDOCTOR_OPTIONS - asciidoctor command options
|
||||
# DEPENDS - dependent files
|
||||
function (document)
|
||||
cmake_parse_arguments (_args "HTML" "SOURCE;LANG;OUTPUT" "ASCIIDOCTOR_OPTIONS;PDF;DEPENDS" ${ARGN})
|
||||
get_filename_component (_source_path ${_args_SOURCE} PATH)
|
||||
get_filename_component (_source_name ${_args_SOURCE} NAME)
|
||||
get_filename_component (_output_name_we ${_args_SOURCE} NAME_WE)
|
||||
|
||||
# HTML
|
||||
if (${_args_HTML})
|
||||
set (_html_file ${CMAKE_CURRENT_BINARY_DIR}/${_output_name_we}_${lang}.html)
|
||||
add_custom_command (
|
||||
OUTPUT ${_html_file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_source_path}/${lang}
|
||||
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ${_args_ASCIIDOCTOR_OPTIONS}
|
||||
-b html5
|
||||
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
|
||||
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
|
||||
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}
|
||||
-a VERSION=${wsjtx_VERSION}
|
||||
--out-file=${_html_file} ${_source_name}
|
||||
DEPENDS ${_args_DEPENDS}
|
||||
COMMENT "Generating ${_html_file}"
|
||||
)
|
||||
list (APPEND _output_files ${_html_file})
|
||||
endif (${_args_HTML})
|
||||
|
||||
# PDF
|
||||
if (_args_PDF AND EXISTS ${FOPUB_EXECUTABLE})
|
||||
set (_docbook_file ${CMAKE_CURRENT_BINARY_DIR}/${_output_name_we}_${lang}.xml)
|
||||
set (_pdf_file_we ${CMAKE_CURRENT_BINARY_DIR}/${_output_name_we}_${lang})
|
||||
if (${lang} MATCHES "^(en|es|fr)$") # en-us, fr-ca and es-{mx,co} use US-Letter or equivalent
|
||||
set (_usl_commands
|
||||
COMMAND ${FOPUB_EXECUTABLE} ARGS ${_docbook_file} ${_args_PDF} -param paper.type USLetter
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E rename ${_pdf_file_we}.pdf '${_pdf_file_we} \(USLetter\).pdf'
|
||||
)
|
||||
list (APPEND _output_files "${_pdf_file_we} (USLetter).pdf")
|
||||
endif ()
|
||||
list (APPEND _output_files "${_pdf_file_we}.pdf")
|
||||
add_custom_command (
|
||||
OUTPUT ${_docbook_file} ${_output_files}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_source_path}/${lang}
|
||||
COMMAND ${ASCIIDOCTOR_EXECUTABLE} ARGS ${_args_ASCIIDOCTOR_OPTIONS}
|
||||
-b docbook
|
||||
-a data-uri!
|
||||
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
|
||||
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
|
||||
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}
|
||||
-a VERSION=${wsjtx_VERSION}
|
||||
-D ${CMAKE_CURRENT_BINARY_DIR}
|
||||
-o ${_docbook_file} ${_source_name}
|
||||
${_usl_commands}
|
||||
COMMAND ${FOPUB_EXECUTABLE} ARGS ${_docbook_file} ${_args_PDF} -param paper.type A4
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E rename ${_pdf_file_we}.pdf '${_pdf_file_we}.pdf'
|
||||
DEPENDS ${_args_DEPENDS}
|
||||
COMMENT "Generating ${_output_files}"
|
||||
)
|
||||
endif (_args_PDF AND EXISTS ${FOPUB_EXECUTABLE})
|
||||
|
||||
set (${_args_OUTPUT} ${_output_files} PARENT_SCOPE)
|
||||
endfunction (document)
|
||||
|
||||
set (htmls)
|
||||
set (pdfs)
|
||||
foreach (lang ${LANGUAGES})
|
||||
set (_sources)
|
||||
foreach (_src ${UG_SRCS} ${UG_IMGS})
|
||||
list (APPEND _sources "user_guide/${lang}/${_src}")
|
||||
endforeach ()
|
||||
document(
|
||||
HTML
|
||||
SOURCE user_guide/wsjtx-main.adoc
|
||||
LANG "${lang}"
|
||||
OUTPUT html
|
||||
ASCIIDOCTOR_OPTIONS -d book -a data-uri -a toc=left -a max-width=1024px
|
||||
DEPENDS ${common_SRCS} ${_sources}
|
||||
)
|
||||
document(
|
||||
PDF -param body.font.master 11 -param body.font.family "'Noto Sans, Helvetica, sans-serif'" -param title.font.family "'Noto Serif, Times New Roman, serif'" -param page.margin.inner 1cm -param page.margin.outer 1cm -param page.margin.top 0.75cm -param page.margin.bottom 0.5cm -param generate.toc 0
|
||||
SOURCE user_guide/wsjtx-main.adoc
|
||||
LANG "${lang}"
|
||||
OUTPUT pdf
|
||||
ASCIIDOCTOR_OPTIONS -d book
|
||||
DEPENDS ${common_SRCS} ${_sources}
|
||||
)
|
||||
list (APPEND htmls "${html}")
|
||||
list (APPEND pdfs "${pdf}")
|
||||
endforeach ()
|
||||
|
||||
add_custom_target (docs ALL DEPENDS ${htmls} ${pdfs})
|
||||
|
||||
foreach (_html ${htmls})
|
||||
get_filename_component (_path ${_html} PATH)
|
||||
get_filename_component (_nwe ${_html} NAME_WE)
|
||||
get_filename_component (_ext ${_html} EXT)
|
||||
string (REGEX REPLACE "_en$" "" _nwe ${_nwe})
|
||||
install (FILES
|
||||
${_html}
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||
RENAME ${_nwe}-${wsjtx_VERSION}${_ext}
|
||||
#COMPONENT runtime
|
||||
)
|
||||
endforeach ()
|
||||
@@ -1,40 +0,0 @@
|
||||
This folder contains the sources of WSJT-X documentation. To build
|
||||
these you will need the asciidoctor tool installed.
|
||||
|
||||
If you do not wish to build the documentation, it is possible to skip
|
||||
this directory in the WSJT-X build by setting the CMake option
|
||||
WSJT_GENERATE_DOCS to OFF in your build tree.
|
||||
|
||||
|
||||
On Linux
|
||||
========
|
||||
|
||||
You will probably have these installed already if you are building the
|
||||
WSJT-X manpages, if you are not you will just need to install
|
||||
asciidoc:
|
||||
|
||||
sudo apt-get install asciidoctor
|
||||
|
||||
or
|
||||
|
||||
sudo yum install asciidoctor
|
||||
|
||||
or whatever your distribution and package management requires.
|
||||
|
||||
|
||||
On Mac OS X
|
||||
===========
|
||||
|
||||
I recommend MacPorts:
|
||||
|
||||
sudo port install rb-rubygems
|
||||
sudo gem install asciidoctor
|
||||
|
||||
|
||||
On Windows
|
||||
==========
|
||||
|
||||
The asciidoctor tool is a Ruby script so you will need to install a
|
||||
version of Ruby. The gem tool is a good way to install asciidoctor:
|
||||
|
||||
gem install asciidoctor
|
||||
@@ -1,17 +0,0 @@
|
||||
The following are established communication channels for the WSJT Group.
|
||||
For updates and other information on the continuing development of _WSJT_,
|
||||
_MAP65_, _WSPR_, _WSPR-X_, and _WSJT-X_ you are invited to subscribe to the
|
||||
{dev_mail_list}.
|
||||
|
||||
.General Information
|
||||
* Main Site: {homepage}
|
||||
* Development Site: {projsummary}
|
||||
|
||||
.Development Related
|
||||
* Project Manager, email: {joe_taylor}
|
||||
* Development Email: {devmail1}
|
||||
* Development Mailing List (join): {dev_mail_list}
|
||||
* Repository Updates, (join): {dev_mail_svn}
|
||||
|
||||
.Community Related
|
||||
* Discussion Board: {wsjt_yahoo_group}
|
||||
@@ -1,29 +0,0 @@
|
||||
include::./links.adoc[]
|
||||
_{prog}_ is free software: you may redistribute and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
_{prog}_ is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this documentation. If not, see {gnu_gpl}.
|
||||
|
||||
Except where otherwise noted, all algorithms, protocol designs, source
|
||||
code, and supporting files contained in the _{prog}_ package are the
|
||||
intellectual property of the program's authors. The authors assert
|
||||
*Copyright ownership* of this material, whether or not such copyright
|
||||
notice appears in each individual file. Others who make fair use of
|
||||
our work under terms of the GNU General Public License must display
|
||||
the following copyright notice prominently:
|
||||
|
||||
*The algorithms, source code, look-and-feel of _{prog}_ and related
|
||||
programs, and protocol specifications for the modes FSK441, FT8, JT4,
|
||||
JT6M, JT9, JT65, JTMS, QRA64, ISCAT, and MSK144 are Copyright (C)
|
||||
2001-2018 by one or more of the following authors: Joseph Taylor,
|
||||
K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo,
|
||||
IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR;
|
||||
Philip Karn, KA9Q; and other members of the WSJT Development Group.*
|
||||
@@ -1,128 +0,0 @@
|
||||
////
|
||||
Link file to hold all links
|
||||
File Location: ./doc/common/links.adoc
|
||||
Usage example: include::../common/links.adoc[]
|
||||
Syntax: [link-id] [link] [displayed text]
|
||||
|
||||
Example:
|
||||
:pskreporter: http://pskreporter.info/pskmap.html[PSK Reporter]
|
||||
|
||||
[link-id] = :pskreporter:
|
||||
[link] http://pskreporter.info/pskmap.html
|
||||
[displayed text] PSK Reporter
|
||||
|
||||
Perform searches from the doc root directory: doc
|
||||
Search: grep -rl --exclude-dir="*\.svn" {pskreporter} .
|
||||
grep -rl --exclude-dir="*\.svn" PSK Reporter .
|
||||
grep -rl --exclude-dir="*\.svn" {devsvn} .
|
||||
grep -rl --exclude-dir="*\.svn" {kvasd} .
|
||||
grep -rl --exclude-dir="*\.svn" {ntpsetup} .
|
||||
|
||||
Include links.adoc: grep -rl --exclude-dir="*\.svn" pskreporter .
|
||||
Exclude links.adoc: grep -rl --exclude-dir="*\.svn" {pskreporter} .
|
||||
|
||||
Note(s):
|
||||
a). Don't forget a space then "." at the end.
|
||||
|
||||
b). To include links.adoc file itself, remove the brackets {} from
|
||||
the pattern search:
|
||||
|
||||
c). Look at each of the files listed to ensure the [displayed text]
|
||||
still makes sense in the caption. If not, just add another link. Be
|
||||
aware of the translators requirements by trying to keep the displayed
|
||||
text language agnostic or neutral e.g. use a proper noun like a
|
||||
persons name or a document title in the language of the linked
|
||||
document. Do not use plain English generic words for link text link
|
||||
"here".
|
||||
|
||||
d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
|
||||
////
|
||||
|
||||
// General URL's
|
||||
//:launchpadac6sl: https://launchpad.net/~jnogatch/+archive/wsjtx[WSJT-X Linux Packages]
|
||||
:alarmejt: http://f5jmh.free.fr/index.php?page=english[AlarmeJT]
|
||||
:asciidoc_cheatsheet: http://powerman.name/doc/asciidoc[AsciiDoc Cheatsheet]
|
||||
:asciidoc_help: http://www.methods.co.nz/asciidoc/userguide.html[AsciiDoc User Guide]
|
||||
:asciidoc_questions: http://www.methods.co.nz/asciidoc/faq.html[AsciiDoc FAQ]
|
||||
:asciidoc_syntax: http://xpt.sourceforge.net/techdocs/nix/tool/asciidoc-syn/ascs01-AsciiDocMarkupSyntaxQuickSummary/single/[AsciiDoc Syntax]
|
||||
:asciidoctor_style: http://asciidoctor.org/docs/asciidoc-writers-guide/#delimited-blocks[AsciiDoctor Styles Guide]
|
||||
:asciidoctor_syntax: http://asciidoctor.org/docs/asciidoc-writers-guide/#delimited-blocks[AsciiDoctor Syntax Guide]
|
||||
:cc_by_sa: http://creativecommons.org/licenses/by-sa/3.0/[Commons Attribution-ShareAlike 3.0 Unported License]
|
||||
:debian32: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_i386.deb[wsjtx_{VERSION}_i386.deb]
|
||||
:debian64: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_amd64.deb[wsjtx_{VERSION}_amd64.deb]
|
||||
:raspbian: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_armhf.deb[wsjtx_{VERSION}_armhf.deb]
|
||||
:debian: http://www.debian.org/[Debian]
|
||||
:dev_guide: http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/wsjt-dev-guide.html[Dev-Guide]
|
||||
:devsvn1: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[Devel-SVN]
|
||||
:devsvn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[SourceForge]
|
||||
:dimension4: http://www.thinkman.com/dimension4/[Thinking Man Software]
|
||||
:download: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[Download Page]
|
||||
:dxatlas: http://www.dxatlas.com/[Afreet Software, Inc.]
|
||||
:dxlcommander: http://www.dxlabsuite.com/commander/[Commander]
|
||||
:dxlsuite: http://www.dxlabsuite.com/[DX Lab Suite]
|
||||
:fedora32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-i686.rpm[wsjtx-{VERSION}-i686.rpm]
|
||||
:fedora64: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-x86_64.rpm[wsjtx-{VERSION}-x86_64.rpm]
|
||||
:fmt_arrl: http://www.arrl.org/frequency-measuring-test[ARRL FMT Info]
|
||||
:fmt_group: https://groups.yahoo.com/neo/groups/FMT-nuts/info[FMT Group]
|
||||
:fmt_k5cm: http://www.k5cm.com/[FMT Event Info]
|
||||
:fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup]
|
||||
:ft8_tips: http://www.physics.princeton.edu/pulsar/K1JT/FT8_Operating_Tips.pdf[here]
|
||||
:ft8_DXped: http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf[FT8 DXpedition Mode]
|
||||
:gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License]
|
||||
:homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page]
|
||||
:hrd: http://www.hrdsoftwarellc.com/[Ham Radio Deluxe]
|
||||
:jt4eme: http://physics.princeton.edu/pulsar/K1JT/WSJT-X_1.6.0_for_JT4_v7.pdf[Using WSJT-X for JT4 EME Operation]
|
||||
:jt65protocol: http://physics.princeton.edu/pulsar/K1JT/JT65.pdf[QEX]
|
||||
:jtalert: http://hamapps.com/[JT-Alert]
|
||||
:launchpadki7mt: https://launchpad.net/~ki7mt[KI7MT PPA's]
|
||||
:log4om: http://www.log4om.com[Log4OM]
|
||||
:lunarEchoes: http://physics.princeton.edu/pulsar/K1JT/LunarEchoes_QEX.pdf[QEX]
|
||||
:msk144: http://physics.princeton.edu/pulsar/k1jt/MSK144_Protocol_QEX.pdf[QEX]
|
||||
:msys_url: http://sourceforge.net/projects/mingwbuilds/files/external-binary-packages/[MSYS Download]
|
||||
:ntpsetup: http://www.satsignal.eu/ntp/setup.html[Network Time Protocol Setup]
|
||||
:osx_instructions: http://physics.princeton.edu/pulsar/K1JT/OSX_Readme[Mac OS X Install Instructions]
|
||||
:ppa: http://en.wikipedia.org/wiki/Personal_Package_Archive[PPA]
|
||||
:projsummary: http://sourceforge.net/projects/wsjt/[Project Summary]
|
||||
:pskreporter: http://pskreporter.info/pskmap.html[PSK Reporter]
|
||||
:sourceforge: https://sourceforge.net/user/registration[SourceForge]
|
||||
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
|
||||
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
|
||||
:wsjt_yahoo_group: https://groups.yahoo.com/neo/groups/wsjtgroup/info[WSJT Group]
|
||||
:wsjtx: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X]
|
||||
:wspr0_guide: http://www.physics.princeton.edu/pulsar/K1JT/WSPR0_Instructions.TXT[WSPR0 Guide]
|
||||
:wspr: http://physics.princeton.edu/pulsar/K1JT/wspr.html[WSPR Home Page]
|
||||
:wsprnet: http://wsprnet.org/drupal/[WSPRnet]
|
||||
:wsprnet_activity: http://wsprnet.org/drupal/wsprnet/activity[WSPRnet Activity page]
|
||||
|
||||
// Download Links
|
||||
:cty_dat: http://www.country-files.com/cty/[Amateur Radio Country Files]
|
||||
:jtbridge: http://jt-bridge.eller.nu/[JT-Bridge]
|
||||
:jtsdk_doc: http://physics.princeton.edu/pulsar/K1JT/JTSDK-DOC.exe[Download]
|
||||
:jtsdk_installer: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/JTSDK-2.0.0-B2-Win32.exe/download[Download]
|
||||
:jtsdk_omnirig: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/base/contrib/OmniRig.zip/download[Download]
|
||||
:jtsdk_py: http://physics.princeton.edu/pulsar/K1JT/JTSDK-PY.exe[Download]
|
||||
:jtsdk_qt: http://physics.princeton.edu/pulsar/K1JT/JTSDK-QT.exe[Download]
|
||||
:jtsdk_vcredist: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/base/contrib/vcredist_x86.exe/download[Download]
|
||||
:nh6z: http://www.nh6z.net/Amatuer_Radio_Station_NH6Z/Other_Peoples_Software.html[here]
|
||||
:omnirig: http://www.dxatlas.com/OmniRig/Files/OmniRig.zip[Omni-Rig]
|
||||
:osx: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-Darwin.dmg[wsjtx-{VERSION}-Darwin.dmg]
|
||||
:QRA64_EME: http://physics.princeton.edu/pulsar/K1JT/QRA64_EME.pdf[QRA64 for microwave EME]
|
||||
:svn: http://subversion.apache.org/packages.html#windows[Subversion]
|
||||
:win32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-win32.exe[wsjtx-{VERSION}-win32.exe]
|
||||
:wsjt-devel: https://lists.sourceforge.net/lists/listinfo/wsjt-devel[here]
|
||||
:wsjt_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[WSJT Source Repository]
|
||||
:wspr_code: http://physics.princeton.edu/pulsar/K1JT/WSPRcode.exe[WSPRcode.exe]
|
||||
:wspr_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/branches/wspr/[WSPR Source Repository]
|
||||
|
||||
// MAIL-TO links
|
||||
:alex_efros: mailto:powerman@powerman.name[Alex Efros]
|
||||
:bill_somerville: mailto:g4wjs -at- c l a s s d e s i g n -dot- com [G4WJS]
|
||||
:dev_mail_list: http://sourceforge.net/mailarchive/forum.php?forum_name=wsjt-devel[WSJT Developers Email List]
|
||||
:dev_mail_svn: https://sourceforge.net/auth/subscriptions/[WSJT SVN Archives]
|
||||
:devmail: mailto:wsjt-devel@lists.sourceforge.net[wsjt-devel@lists.sourceforge.net]
|
||||
:devmail1: mailto:wsjt-devel@lists.sourceforge.net[Post Message]
|
||||
:wsjtgroup_mail: mailto:wsjtgroup@yahoogroups.com[Post Message]
|
||||
:greg_beam: mailto:ki7mt@yahoo.com[KI7MT]
|
||||
:joe_taylor: mailto:joe@princeton.edu[K1JT]
|
||||
:stuart_rackman: mailto:srackham@gmail.com[Stuart Rackham]
|
||||
@@ -1,29 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
The _WSJT_ project was started in 2001. Since 2005 it has been an
|
||||
Open Source project, and it now includes programs _WSJT_, _MAP65_,
|
||||
_WSPR_, _WSJT-X_, and _WSPR-X_. All code is licensed under the
|
||||
GNU Public License (GPL). Many users of these programs, too numerous
|
||||
to mention here individually, have contributed suggestions and advice
|
||||
that have greatly aided the development of _WSJT_ and its sister
|
||||
programs.
|
||||
|
||||
For _WSJT-X_ in particular, we acknowledge contributions from *AC6SL,
|
||||
AE4JY, DJ0OT, G3WDG, G4KLA, G4WJS, IV3NWV, IW3RAB, K3WYC, K9AN,
|
||||
KA6MAL, KA9Q, KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR, VE1SKY, VK3ACF,
|
||||
VK4BDJ, VK7MO, W4TI, W4TV, and W9MDB*. Each of these amateurs has helped to
|
||||
bring the program’s design, code, testing, and/or documentation to
|
||||
its present state.
|
||||
|
||||
Most of the color palettes for the _WSJT-X_ waterfall were copied from
|
||||
the excellent, well documented, open-source program _fldigi_, by *W1HKJ*
|
||||
and friends.
|
||||
|
||||
We use development tools and libraries from many sources. We
|
||||
particularly wish to acknowledge importance of the GNU Compiler
|
||||
Collection from the Free Software Foundation, the "clang" compiler
|
||||
from LLVM at the University of Illinois, and the Qt Project from Digia
|
||||
PLC. Other important resources include the FFTW library by Matteo
|
||||
Frigo and Steven G. Johnson; SLALIB, the Positional Astronomy Library
|
||||
by P. T. Wallace; and a high-precision planetary ephemeris and
|
||||
associated software from NASA's Jet Propulsion Laboratory.
|
||||
@@ -1,57 +0,0 @@
|
||||
A text box entitled Astronomical Data provides information needed for
|
||||
tracking the sun or moon, compensating for EME Doppler shift, and
|
||||
estimating EME Doppler spread and path degradation. Toggle the
|
||||
*Astronomical data* on the *View* menu to display or hide this window.
|
||||
|
||||
image::AstroData_2.png[align="center",alt="Astronomical Data"]
|
||||
|
||||
Available information includes the current UTC *Date* and time; *Az*
|
||||
and *El*, azimuth and elevation of the moon at your own location, in
|
||||
degrees; *SelfDop*, *Width*, and *Delay*, the Doppler shift, full
|
||||
limb-to-limb Doppler spread in Hz, and delay of your own EME echoes in
|
||||
seconds; and *DxAz* and *DxEl*, *DxDop*, and *DxWid*, corresponding
|
||||
parameters for a station located at the *DX Grid* entered on the main
|
||||
window. These numbers are followed by *Dec*, the declination of the
|
||||
moon; *SunAz* and *SunEl*, the azimuth and elevation of the Sun;
|
||||
*Freq*, your stated operating frequency in MHz; *Tsky*, the estimated
|
||||
sky background temperature in the direction of the moon, scaled to the
|
||||
operating frequency; *Dpol*, the spatial polarization offset in
|
||||
degrees; *MNR*, the maximum non-reciprocity of the EME path in dB,
|
||||
owing to a combination of Faraday rotation and spatial polarization;
|
||||
and finally *Dgrd*, an estimate of the signal degradation in dB,
|
||||
relative to the best possible time with the moon at perigee in a cold
|
||||
part of the sky.
|
||||
|
||||
On the higher microwave bands, where Faraday rotation is minimal and
|
||||
linear polarization is often used, spatial offset will reduce signal
|
||||
levels. Some stations have implemented mechanical polarisation
|
||||
adjustment to overcome this loss, and the amount of rotation needed is
|
||||
predicted in real time by the value of *Dpol*. Positive Dpol means
|
||||
that the antenna should be rotated in a clockwise direction looking
|
||||
from behind the antenna towards the moon. For a dish antenna, the
|
||||
feed should similarly be rotated clockwise looking into the mouth of
|
||||
the feed. A negative value for Dpol means anticlockwise rotation.
|
||||
|
||||
|
||||
The state of the art for establishing three-dimensional locations of
|
||||
the sun, moon, and planets at a specified time is embodied in a
|
||||
numerical model of the solar system maintained at the Jet Propulsion
|
||||
Laboratory. The model has been numerically integrated to produce
|
||||
tabular data that can be interpolated with very high accuracy. For
|
||||
example, the celestial coordinates of the moon or a planet can be
|
||||
determined at a specified time to within about 0.0000003 degrees. The
|
||||
JPL ephemeris tables and interpolation routines have been incorporated
|
||||
into _WSJT-X_. Further details on accuracy, especially concerning
|
||||
calculated EME Doppler shifts, are described in {lunarEchoes} for
|
||||
November-December, 2016.
|
||||
|
||||
The sky background temperatures reported by _WSJT-X_ are derived from
|
||||
the all-sky 408 MHz map of Haslam et al. (Astronomy and Astrophysics
|
||||
Supplement Series, 47, 1, 1982), scaled by frequency to the -2.6
|
||||
power. This map has angular resolution of about 1 degree, and of
|
||||
course most amateur EME antennas have much broader beamwidths than
|
||||
this. Your antenna will therefore smooth out the hot spots
|
||||
considerably, and the observed extremes of sky temperature will be
|
||||
less. Unless you understand your sidelobes and ground reflections
|
||||
extremely well, it is unlikely that more accurate sky temperatures
|
||||
would be of much practical use.
|
||||
@@ -1,4 +0,0 @@
|
||||
// Status=review
|
||||
[[CONFIG_DETAILS]]
|
||||
|
||||
Are we here?
|
||||
@@ -1,80 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
At the center of the main window are a number of controls used when
|
||||
making QSOs. Controls not relevant to a particular mode or submode
|
||||
may be "grayed out" (disabled) or removed from the display.
|
||||
|
||||
//.Misc Controls Center
|
||||
image::misc-controls-center.png[align="center",alt="Misc Controls Center"]
|
||||
|
||||
* Check *Tx even* to transmit in even-numbered UTC minutes or
|
||||
sequences, starting at 0. Uncheck this box to transmit in the odd
|
||||
sequences. The correct selection is made automatically when you
|
||||
double-click on a decoded text line, as described in the
|
||||
<<TUTORIAL,Basic Operating Tutorial>>.
|
||||
|
||||
* The Tx and Rx audio frequencies can be set automatically by
|
||||
double-clicking on decoded text or a signal in the waterfall. They
|
||||
can also be adjusted using the spinner controls.
|
||||
|
||||
* You can force Tx frequency to the current Rx frequency by clicking
|
||||
the *Tx<-Rx* button, and vice-versa for *Rx<-Tx*. The on-the-air
|
||||
frequency of your lowest JT9 or JT65 tone is the sum of dial frequency
|
||||
and audio Tx frequency.
|
||||
|
||||
* Check the box *Lock Tx=Rx* to make the frequencies always track one
|
||||
another.
|
||||
|
||||
IMPORTANT: In general we do not recommend using *Lock Tx=Rx* since it
|
||||
encourages poor radio etiquette when running a frequency. With this
|
||||
box checked, your own Tx frequency will move around following your
|
||||
callers.
|
||||
|
||||
* For modes lacking a multi-decode feature, or when *Enable
|
||||
VHF/UHF/Microwave features* has been checked on the *Settings ->
|
||||
General* tab, the *F Tol* control sets a frequency toilerance range
|
||||
over which decoding will be attempted, centered on the Rx frequency.
|
||||
|
||||
* The *Report* control lets you change a signal report that has been
|
||||
inserted automatically. Typical reports for the various modes fall in
|
||||
the range –30 to +20 dB. Remember that JT65 reports saturate at an
|
||||
upper limit of -1 dB.
|
||||
|
||||
TIP: Consider reducing power if your QSO partner reports your
|
||||
signal above -5 dB in one of the _WSJT-X_ slow modes. These are
|
||||
supposed to be weak signal modes!
|
||||
|
||||
* In some circumstances, especially on VHF and higher bands, you can
|
||||
select a supported submode of the active mode by using the *Submode*
|
||||
control. The *Sync* control sets a minimum threshold for establishing
|
||||
time and frequency synchronization with a received signal.
|
||||
|
||||
* Spinner control *T/R xx s* sets sequence lengths for transmission
|
||||
and reception in ISCAT, MSK144, and the fast JT9 modes.
|
||||
|
||||
* With *Split operation* activated on the *Settings -> Radio* tab, in
|
||||
MSK144 and the fast JT9 submodes you can activate the spinner control
|
||||
*Tx CQ nnn* by checking the box to its right. The program will then
|
||||
generate something like `CQ nnn K1ABC FN42` for your CQ message, where
|
||||
`nnn` is the kHz portion of your current operating frequency,
|
||||
in the range 010 to 999. Your CQ
|
||||
message *Tx6* will then be transmitted at the calling frequency
|
||||
selected in the *Tx CQ nnn* spinner control. All other messages will
|
||||
be transmitted at your current operating frequency. On reception,
|
||||
when you double-click on a message like `CQ nnn K1ABC FN42` your rig
|
||||
will QSY to the specified frequency so you can call the station at his
|
||||
specified response frequency.
|
||||
|
||||
* Checkboxes at bottom center of the main window control special
|
||||
features for particular operating modes:
|
||||
|
||||
** *Sh* enables shorthand messages in JT4, JT65, QRA64 and MSK144 modes
|
||||
|
||||
** *Fast* enables fast JT9 submodes
|
||||
|
||||
** *Auto Seq* enables auto-sequencing of Tx messages
|
||||
|
||||
** *Call 1st* enables automatic response to the first decoded
|
||||
responder to your CQ
|
||||
|
||||
** *Tx6* toggles between two types of shorthand messages in JT4 mode
|
||||
@@ -1,45 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
Controls related to frequency selection, received audio level, the
|
||||
station being called, and date and time are found at lower left of the
|
||||
main window:
|
||||
|
||||
//.Misc Controls Left
|
||||
image::misc-main-ui.png[align="center",alt="Misc Menu Items"]
|
||||
|
||||
* A drop-down list of frequencies and bands at upper left lets you
|
||||
select the operating band and sets dial frequency to a value taken
|
||||
from the *Frequencies* tab on the *Settings* window. If CAT control
|
||||
is active the radio's dial frequency will be set accordingly; if not,
|
||||
you must tune the radio manually.
|
||||
|
||||
* Alternatively, you can enter a frequency (in MHz) or band name in
|
||||
recognized ADIF format, for example 630m, 20m, or 70cm. The band-name
|
||||
format works only if a working frequency has been set for that band
|
||||
and mode, in which case the first such match is selected.
|
||||
|
||||
* You can also enter a frequency increment in kHz above the currently
|
||||
displayed integer MHz. For example, if the displayed frequency is
|
||||
10,368.100, enter `165k` (don't forget the `k`!) to QSY to 10,368.165.
|
||||
|
||||
* A small colored circle appears in green if the CAT control is
|
||||
activated and functional. The green circle contains the character S
|
||||
if the rig is detected to be in *Split* mode. The circle becomes red
|
||||
if you have requested CAT control but communication with the radio has
|
||||
been lost.
|
||||
|
||||
TIP: Many Icom rigs cannot be queried for split status, current VFO or
|
||||
split transmit frequency. When using _WSJT-X_ with such radios you
|
||||
should not change the current VFO, split status or dial frequency
|
||||
using controls on the radio.
|
||||
|
||||
* If *DX Grid* contains a valid Maidenhead locator, the corresponding
|
||||
great-circle azimuth and distance from your location are displayed.
|
||||
|
||||
* The program can maintain a database of callsigns and locators for
|
||||
future reference. Click *Add* to insert the present call and locator
|
||||
in the database; click *Lookup* to retrieve the locator for a
|
||||
previously stored call. This feature is mainly useful for situations
|
||||
in which the number of active stations is modest and reasonably
|
||||
stable, such as EME (Earth-Moon-Earth) communication. The callsign
|
||||
file name is `CALL3.TXT`.
|
||||
@@ -1,69 +0,0 @@
|
||||
// Status=review
|
||||
The following controls appear just under the decoded text windows on
|
||||
the main screen:
|
||||
|
||||
//.Main UI
|
||||
image::main-ui-controls.png[align="center",width=650,alt="Main UI Controls"]
|
||||
|
||||
* When *CQ only* is checked, only messages from stations calling CQ will
|
||||
be displayed in the left text panel.
|
||||
|
||||
* *Log QSO* raises a dialog window pre-filled with known information
|
||||
about a QSO you have nearly completed. You can edit or add to this
|
||||
information before clicking *OK* to log the QSO. If you check *Prompt
|
||||
me to log QSO* on the *Settings -> Reporting* tab, the program will
|
||||
raise the confirmation screen automatically when you send a message
|
||||
containing +73+. *Start Date* and *Start Time* are set when you click
|
||||
to send the *Tx 2* or *Tx 3* message, and backed up by one or two
|
||||
sequence lengths, respectively. (Note that the actual start time may
|
||||
have been earlier if repeats of early transmissions were required.)
|
||||
End date and time are set when the *Log QSO* screen is invoked.
|
||||
|
||||
//.Log QSO Window
|
||||
image::log-qso.png[align="center",alt="Log QSO"]
|
||||
|
||||
* *Stop* will terminate normal data acquisition in case you want to
|
||||
freeze the waterfall or open and explore a previously recorded audio
|
||||
file.
|
||||
|
||||
* *Monitor* toggles normal receive operation on or off. This button
|
||||
is highlighted in green when the _WSJT-X_ is receiving. If you are
|
||||
using CAT control, toggling *Monitor* OFF relinquishes control of the
|
||||
rig; if *Monitor returns to last used frequency* is selected on the
|
||||
*Settings | General* tab, toggling *Monitor* back ON will return to
|
||||
the original frequency.
|
||||
|
||||
* *Erase* clears the right-hand decoded text window.
|
||||
Double-clicking *Erase* clears both text windows.
|
||||
|
||||
TIP: Right-clicking on either text window brings up a context menu
|
||||
with several options (including *Erase*) which operate on that window
|
||||
alone.
|
||||
|
||||
* *Clear Avg* is present only in modes that support message averaging.
|
||||
It provides a way to erase the accumulating information, thus
|
||||
preparing to start a new average.
|
||||
|
||||
* *Decode* tells the program to repeat the decoding procedure at the
|
||||
Rx frequency (green marker on waterfall scale), using the most recently
|
||||
completed sequence of received data.
|
||||
|
||||
* *Enable Tx* toggles automatic T/R sequencing mode on or off and
|
||||
highlights the button in red when ON. A transmission will start at
|
||||
the beginning of the selected (odd or even) sequence, or immediately
|
||||
if appropriate. Toggling the button to OFF during a transmission
|
||||
allows the current transmission to finish.
|
||||
|
||||
* *Halt Tx* terminates a transmission immediately and disables
|
||||
automatic T/R sequencing.
|
||||
|
||||
* *Tune* toggles the program into Tx mode and generates an unmodulated
|
||||
carrier at the specified Tx frequency (red marker on waterfall scale).
|
||||
This process is useful for adjusting an antenna tuner or tuning an
|
||||
amplifier. The button is highlighted in red while *Tune* is active.
|
||||
Toggle the button a second time or click *Halt Tx* to terminate the
|
||||
*Tune* process. Note that activating *Tune* interrupts a receive
|
||||
sequence and will prevent decoding during that sequence.
|
||||
|
||||
* Uncheck the box *Menus* to make the top-of-window menus disappear,
|
||||
leaving more vertical space for decoded messages.
|
||||
@@ -1,66 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
Menus at top of the main window offer many options for configuration
|
||||
and operation. Most of the items are self-explanatory; a few
|
||||
additional details are provided below. Keyboard shortcuts for some
|
||||
frequently used menu items are listed at the right edge of the menu.
|
||||
|
||||
==== _WSJT-X_ menu
|
||||
image::MacAppMenu.png[align="left",alt="Mac App Menu"]
|
||||
|
||||
This menu appears on the Macintosh only. *Settings* appears here,
|
||||
labeled as *Preferences*, rather than on the *File* menu. *About
|
||||
WSJT-X* appears here rather than on the *Help* menu.
|
||||
|
||||
[[FILE_MENU]]
|
||||
==== File menu
|
||||
image::file-menu.png[align="left",alt="File Menu"]
|
||||
|
||||
[[CONFIG_MENU]]
|
||||
==== Configuration Menu
|
||||
image::config-menu.png[align="left",alt="File Menu"]
|
||||
|
||||
Many users prefer to create and use entries on the *Configurations*
|
||||
menu for switching between modes. Simply *Clone* the *Default* entry,
|
||||
*Rename* it as desired, and then make all desired settings for that
|
||||
configuration. These settings will be restored whenever you select
|
||||
that configuration.
|
||||
|
||||
As well as switching between configurations while running _WSJT-X_ you
|
||||
can also start the application from the command line in any desired
|
||||
configuration. Use the command-line option
|
||||
`--config <configuration-name>`, or `-c` for short, as in these
|
||||
examples for configurations `FT8` and `Echo`:
|
||||
|
||||
wsjtx --config FT8
|
||||
wsjtx -c Echo
|
||||
|
||||
[[VIEW_MENU]]
|
||||
==== View Menu
|
||||
image::view-menu.png[align="left",alt="View Menu"]
|
||||
|
||||
[[MODE_MENU]]
|
||||
==== Mode Menu
|
||||
image::mode-menu.png[align="left",alt="Mode Menu"]
|
||||
|
||||
[[DECODE_MENU]]
|
||||
==== Decode Menu
|
||||
image::decode-menu.png[align="left",alt="Decode Menu"]
|
||||
|
||||
[[SAVE_MENU]]
|
||||
[[SAVE-WAV]]
|
||||
==== Save Menu
|
||||
image::save-menu.png[align="left",alt="Save Menu"]
|
||||
|
||||
==== Tools Menu
|
||||
image::tools-menu.png[align="left",alt="Tools Menu"]
|
||||
|
||||
[[HELP_MENU]]
|
||||
==== Help Menu
|
||||
image::help-menu.png[align="left",alt="Help Menu"]
|
||||
|
||||
===== Keyboard Shortcuts (F3)
|
||||
image::keyboard-shortcuts.png[align="left",alt="Keyboard Shortcuts"]
|
||||
|
||||
===== Special Mouse Commands (F5)
|
||||
image::special-mouse-commands.png[align="left",alt="Special Mouse Commands"]
|
||||
@@ -1,61 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
Two arrangements of controls are provided for generating and selecting
|
||||
Tx messages. Controls familiar to users of program _WSJT_
|
||||
appear on *Tab 1*, providing six fields for message entry.
|
||||
Pre-formatted messages for the standard minimal QSO are generated when
|
||||
you click *Generate Std Msgs* or double-click on an appropriate line
|
||||
in one of the decoded text windows.
|
||||
|
||||
//.Traditional Message Menu
|
||||
image::traditional-msg-box.png[align="center",alt="Traditional Message Menu"]
|
||||
|
||||
* Select the next message to be transmitted (at the start of your next
|
||||
Tx sequence) by clicking on the circle under *Next*.
|
||||
|
||||
* To change to a specified Tx message immediately during a
|
||||
transmission, click on a rectangular button under the *Now* label.
|
||||
Changing a Tx message in mid-stream will slightly reduce the chance of
|
||||
a correct decode, but it is usually OK if done in the first 10-20% of
|
||||
a transmission.
|
||||
|
||||
* All six Tx message fields are editable. You can modify an
|
||||
automatically generated message or enter a desired message, keeping in
|
||||
mind the limits on message content. See <<PROTOCOLS,Protocol
|
||||
Specifications>> for details.
|
||||
|
||||
* Click on the pull-down arrow for message #5 to select one of the
|
||||
pre-stored messages entered on the *Settings | Tx Macros* tab.
|
||||
Pressing *Enter* on a modified message #5 automatically adds that
|
||||
message to the stored macros.
|
||||
|
||||
* In some circumstances it may be desirable to make your QSOs as
|
||||
shiort as possible. To configure the program to start contacts with
|
||||
message #2, disable message #1 by double-clicking on its round
|
||||
radio-button or rectangular *Tx 1* button. Similarly, to send RR73
|
||||
rather than RRR for message #4, double-click on one of its buttons.
|
||||
|
||||
The second arrangement of controls for generating and selecting
|
||||
Tx messages appears on *Tab 2* of the Message Control Panel:
|
||||
|
||||
//.New Message Menu
|
||||
image::new-msg-box.png[align="center",alt="New Message Menu"]
|
||||
|
||||
With this setup you normally follow a top-to-bottom sequence of
|
||||
transmissions from the left column if you are calling CQ, or the right
|
||||
column if answering a CQ.
|
||||
|
||||
* Clicking a button puts the appropriate message in the *Gen Msg* box.
|
||||
If you are already transmitting, the Tx message is changed
|
||||
immediately.
|
||||
|
||||
* You can enter and transmit anything (up to 13 characters, including
|
||||
spaces) in the *Free Msg* box.
|
||||
|
||||
* Click on the pull-down arrow in the *Free Msg* box to select a
|
||||
pre-stored macro. Pressing *Enter* on a modified message here
|
||||
automatically adds that message to the table of stored macros.
|
||||
|
||||
TIP: During a transmission the actual message being sent always
|
||||
appears in the first box of the status bar (bottom left of the main
|
||||
screen).
|
||||
@@ -1,23 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
A *Status Bar* at the bottom edge of the main window provides useful
|
||||
information about operating conditions.
|
||||
|
||||
//.Status Bar
|
||||
image::status-bar-a.png[align="left",alt="Status Bar"]
|
||||
|
||||
Labels on the *Status Bar* display such information as the program's
|
||||
current operating state, configuration name, operating mode, and the
|
||||
content of your most recent transmitted message. The first label
|
||||
(operating state) can be Receiving, Tx (for Transmitting), Tune, or
|
||||
the name of file opened from the *File* menu; this label is
|
||||
highlighted in green for Receiving, yellow for Tx, red for Tune, and
|
||||
light blue for a file name. When transmitting, the Tx message is
|
||||
displayed exactly as it will be decoded by receiving stations. The
|
||||
second label (as shown above) will be absent if you are using the
|
||||
*Default* setting on the *Configurations* menu. A progress bar shows
|
||||
the elapsed fraction of a Tx or Rx sequence. Finally, if the Watchdog
|
||||
(WD) timer was enabled on the *settings | General* tab, a label in the
|
||||
lower right-hand corner displays the number of minutes remaining
|
||||
before timeout.
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
The following controls appear at the bottom of the Wide Graph window.
|
||||
Decoding occurs only in the displayed frequency range; otherwise, with
|
||||
the exceptions of *Start NNN Hz* and of *JT65 nnnn JT9* when operating
|
||||
in JT9+JT65 mode, controls on the Wide Graph window have no effect on
|
||||
the decoding process.
|
||||
|
||||
image::wide-graph-controls.png[align="center",alt="Wide Graph Controls"]
|
||||
|
||||
- *Bins/Pixel* controls the displayed frequency resolution. Set this
|
||||
value to 1 for the highest possible resolution, or to higher numbers
|
||||
to compress the spectral display. Normal operation with a convenient
|
||||
window size works well at 2 to 8 bins per pixel.
|
||||
|
||||
- *JT65 nnnn JT9* sets the dividing point (blue marker) for wide-band
|
||||
decoding of JT65 and JT9 signals in *JT9+JT65* mode. The decoder
|
||||
looks for JT65 signals everywhere, but JT9 signals only above this
|
||||
frequency. This setting is stored separately for each band.
|
||||
|
||||
- *Start nnn Hz* sets the low-frequency starting point of the
|
||||
waterfall frequency scale.
|
||||
|
||||
- *N Avg* is the number of successive spectra to be averaged before
|
||||
updating the display. Values around 5 are suitable for normal JT9 and
|
||||
JT65 operation. Adjust *N Avg* to make the waterfall move faster or
|
||||
slower, as desired.
|
||||
|
||||
- A dropdown list below the *Palette* label lets you select from a
|
||||
wide range of waterfall color palettes.
|
||||
|
||||
- Click *Adjust* to activate a window that allows you to create a
|
||||
user-defined palette.
|
||||
|
||||
- Check *Flatten* if you want _WSJT-X_ to compensate for a sloping or
|
||||
uneven response across the received passband. For this feature to
|
||||
work properly, you should restrict the range of displayed frequencies
|
||||
so that only the active part of the spectrum is shown.
|
||||
|
||||
- Select *Current* or *Cumulative* for the spectrum displayed in the
|
||||
bottom one-third of the Wide Graph window. *Current* is the average
|
||||
spectrum over the most recent *N Avg* FFT calculations. *Cumulative*
|
||||
is the average spectrum since the start of the present UTC minute.
|
||||
*Linear Avg* is useful in JT4 mode, especially when short-form
|
||||
messages are used.
|
||||
|
||||
- Four sliders control reference levels and scaling for waterfall
|
||||
colors and the spectrum plot. Values around midscale are usually
|
||||
about right, depending on the input signal level, the chosen palette,
|
||||
and your own preferences. Hover the mouse over a control to display a
|
||||
tip reminding you of its function.
|
||||
|
||||
- *Smoothing* is active only when *Linear Average* has been selected.
|
||||
Smoothing the displayed spectrum over more than one bin can enhance
|
||||
your ability to detect weak EME signals with Doppler spread more than
|
||||
a few Hz.
|
||||
|
||||
[[CONTROLS_FAST]]
|
||||
=== Fast Graph
|
||||
|
||||
The waterfall palette used for the Fast Graph is the same as the one
|
||||
selected on the Wide Graph. Three sliders at the bottom of the Fast
|
||||
Graph window can be used to optimize gain and zero-offset for the
|
||||
displayed information. Hover the mouse over a control to display a
|
||||
tip reminding you of its function. Clicking the *Auto Level* button
|
||||
will produce reasonable settings as a starting point.
|
||||
|
||||
image::fast-graph-controls.png[align="center",alt="Fast Graph Controls"]
|
||||
|
||||
[[CONTROLS_ECHO]]
|
||||
=== Echo Graph
|
||||
|
||||
The following controls appear at the bottom of the Echo Graph:
|
||||
|
||||
image::echo-graph-controls.png[align="center",alt="EchoGraph Controls"]
|
||||
|
||||
- *Bins/Pixel* controls the displayed frequency resolution. Set this
|
||||
value to 1 for the highest possible resolution, or to higher numbers
|
||||
to compress the spectral display.
|
||||
|
||||
- *Gain* and *Zero* sliders control scaling and offset of plotted
|
||||
spectra.
|
||||
|
||||
- *Smooth* values greater than 0 apply running averages to the plotted
|
||||
spectra, thereby smoothing the curves over multiple bins.
|
||||
|
||||
- Label *N* shows the number of echo pulses averaged.
|
||||
|
||||
- Click the *Colors* button to cycle through 6 possible choices of
|
||||
color and line width for the plots.
|
||||
|
||||
[[CONTROLS_MISCELLANEOUS]]
|
||||
=== Miscellaneous
|
||||
|
||||
Most windows can be resized as desired. If you are short of screen
|
||||
space you can make the Main Window and Wide Graph smaller by hiding
|
||||
some controls and labels. To enable this feature type *Ctrl+M* with
|
||||
focus on the appropriate window. (For the Main Window you can select
|
||||
*Hide menus and labels* on the *View* menu.) Type *Ctrl+M* again
|
||||
to make the controls visible once more.
|
||||
@@ -1,39 +0,0 @@
|
||||
_WSJT-X_ is programmed to cooperate closely with several other useful
|
||||
programs.
|
||||
|
||||
* {dxlsuite}, {omnirig}, and {hrd} were described in the section on
|
||||
<<RADIO,rig control>>.
|
||||
|
||||
* {pskreporter}, by Philip Gladstone, is a web server that gathers
|
||||
reception reports sent by various other programs, including _WSJT-X_.
|
||||
The information is made available in near real time on a world map,
|
||||
and also as statistical summaries of various kinds. A number of
|
||||
options are available to the user; for example, you can request a map
|
||||
showing world-wide JT65 activity on all amateur bands over the
|
||||
past hour. Such a map might look like this, where different colors
|
||||
represent different bands:
|
||||
|
||||
image::psk-reporter.png[align="left",alt="PSK Reporter"]
|
||||
|
||||
The following screen shot shows the PSK Reporter map configured to
|
||||
show MSK144 reports:
|
||||
|
||||
image::psk-reporter_2.png[align="left",alt="PSK Reporter"]
|
||||
|
||||
* {jtalert}, by VK3AMA, is available only for Windows. It provides
|
||||
many operating aids including automatic logging to several third-party
|
||||
logging programs, audio and visual alerts following a number of
|
||||
optional alert conditions (decoding of a new DXCC, new state, etc.),
|
||||
and convenient direct access to web services such as callsign lookup.
|
||||
|
||||
image::jtalert.png[align="left",alt="JTAlert-X image"]
|
||||
|
||||
* {alarmejt}, by F5JMH, is available only for Linux. The program keeps
|
||||
its own logbook. It fetches contact information from _WSJT-X_ and
|
||||
provides visual alerts for new DXCC entities and grid squares on the
|
||||
current band, as well as other options.
|
||||
|
||||
* {jtbridge}, by SM0THU, is available for OS X. It works together with
|
||||
logging applications Aether, MacLoggerDX, RUMlog or RUMlogNG. It
|
||||
checks QSO and QSL status of the call and DXCC entity, as well as many
|
||||
other features.
|
||||
@@ -1,155 +0,0 @@
|
||||
=== AP Decoding
|
||||
|
||||
The _WSJT-X_ decoders for JT65, QRA64, and FT8 include optional
|
||||
procedures that use naturally accumulating information during a
|
||||
minimal QSO. This _a priori_ (AP) information increases sensitivity
|
||||
of the decoder by up to 4 dB, at the cost of a slightly higher rate of
|
||||
false decodes.
|
||||
|
||||
For example: when you decide to answer a CQ, you already know your own
|
||||
callsign and that of your potential QSO partner. The software
|
||||
therefore "`knows`" what to expect for 57 of the 72 message bits (28
|
||||
bits for each of two callsigns, 1 bit for message type) in the next
|
||||
received message. The decoder's task can thus be reduced to
|
||||
determining the remaining 15 bits of the message and ensuring that the
|
||||
resulting solution is reliable.
|
||||
|
||||
AP decoding starts by setting AP bits to the hypothesized values, as
|
||||
if they had been received correctly. We then determine whether the
|
||||
remaining message and parity bits are consistent with the hypothesized
|
||||
AP bits, with a specified level of confidence. Successful AP decodes
|
||||
are labeled with an end-of-line indicator of the form `aP`, where `P`
|
||||
is one of the single-digit AP decoding types listed in Table 1. For
|
||||
example, `a2` indicates that the successful decode used MyCall as
|
||||
hypothetically known information.
|
||||
|
||||
[[FT8_AP_INFO_TABLE]]
|
||||
.FT8 AP information types
|
||||
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
||||
|===============================================
|
||||
|aP | Message components
|
||||
|a1 | CQ     ?     ?
|
||||
|a2 | MyCall     ?     ?
|
||||
|a3 | MyCall DxCall     ?
|
||||
|a4 | MyCall DxCall RRR
|
||||
|a5 | MyCall DxCall 73
|
||||
|a6 | MyCall DxCall RR73
|
||||
|===============================================
|
||||
|
||||
If a codeword is found that is judged to have high (but not
|
||||
overwhelmingly high) probability of being correct, a `?` character is
|
||||
appended when the decoded message is displayed. To avoid misleading
|
||||
spots of occasional false decodes, messages so marked are not
|
||||
forwarded to {pskreporter}.
|
||||
|
||||
Table 2 lists the six possible QSO states that are tracked by the
|
||||
_WSJT-X_ auto-sequencer, along with the type of AP decoding that would
|
||||
be attempted in each state.
|
||||
|
||||
[[FT8_AP_DECODING_TYPES_TABLE]]
|
||||
.FT8 AP decoding types for each QSO state
|
||||
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
||||
|===========================================
|
||||
|State |AP type
|
||||
|CALLING STN | 2, 3
|
||||
|REPORT | 2, 3
|
||||
|ROGER_REPORT | 3, 4, 5, 6
|
||||
|ROGERS | 3, 4, 5, 6
|
||||
|SIGNOFF | 3, 1, 2
|
||||
|CALLING CQ | 1, 2
|
||||
|===========================================
|
||||
|
||||
Decoding with _a priori_ information behaves slightly differently
|
||||
in JT65. Some details are provided in Tables 3 and 4.
|
||||
|
||||
[[JT65_AP_INFO_TABLE]]
|
||||
.JT65 AP information types
|
||||
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
||||
|===============================================
|
||||
|aP | Message components
|
||||
|a1 | CQ     ?     ?
|
||||
|a2 | MyCall     ?     ?
|
||||
|a3 | MyCall DxCall     ?
|
||||
|a4 | MyCall DxCall RRR
|
||||
|a5 | MyCall DxCall 73
|
||||
|a6 | MyCall DxCall DxGrid
|
||||
|a7 | CQ DxCall DxGrid
|
||||
|===============================================
|
||||
|
||||
[[JT65_AP_DECODING_TYPES_TABLE]]
|
||||
.JT65 AP decoding types for each QSO state
|
||||
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
||||
|===========================================
|
||||
|State |AP type
|
||||
|CALLING STN | 2, 3, 6, 7
|
||||
|REPORT | 2, 3
|
||||
|ROGER_REPORT | 3, 4, 5
|
||||
|ROGERS | 3, 4, 5
|
||||
|SIGNOFF | 2, 3, 4, 5
|
||||
|CALLING CQ | 1, 2, 6
|
||||
|===========================================
|
||||
|
||||
|
||||
=== Decoded Lines
|
||||
|
||||
Displayed information accompanying decoded messages generally includes UTC,
|
||||
signal-to-noise ratio in dB, time offset DT in seconds, and
|
||||
audio frequency in Hz. Some modes include additional information such
|
||||
as frequency offset from nominal (DF), frequency drift (Drift or F1),
|
||||
or distance (km or mi).
|
||||
|
||||
There may also be some cryptic characters with special meanings
|
||||
summarized in the following Table:
|
||||
|
||||
[[DECODED_LINES_TABLE]]
|
||||
.Notations used on decoded text lines
|
||||
[width="50%",cols="h,3*^",frame=topbot,options="header"]
|
||||
|===========================================
|
||||
|Mode |Mode character|Sync character|End of line information
|
||||
|FT8 | ~ | | ?   aP
|
||||
|JT4 | $ | *, # | f, fN, dNC
|
||||
|JT9 | @ | |
|
||||
|JT65 | # | |
|
||||
|JT65 VHF| # | *, # | f, fN, dNC
|
||||
|QRA64 | : | * | R
|
||||
|ISCAT | | * | M N C T
|
||||
|MSK144 | & | | N H E
|
||||
|===========================================
|
||||
Sync character::
|
||||
`*` - Normal sync +
|
||||
`#` - Alternate sync
|
||||
|
||||
End of line information::
|
||||
`?` - Decoded with lower confidence +
|
||||
`a` - Decoded with aid of some a priori (AP) information +
|
||||
`C` - Confidence indicator [ISCAT and Deep Search; (0-9,*)] +
|
||||
`d` - Deep Search algorithm +
|
||||
`E` - Size of MSK eye diagram opening - if negative, the eye is closed +
|
||||
`f` - Franke-Taylor or Fano algorithm +
|
||||
`H` - Number of bit errors corrected +
|
||||
`M` - Message length (characters) +
|
||||
`N` - Number of Rx intervals or frames averaged +
|
||||
`P` - Number indicating type of AP information (Table 1, above) +
|
||||
`R` - Return code from QRA64 decoder +
|
||||
`T` - Length of analyzed region (s)
|
||||
|
||||
Table 6 below shows the meaning of the return codes R in QRA64 mode.
|
||||
|
||||
[[QRA64_AP_INFO_TABLE]]
|
||||
.QRA64 AP return codes
|
||||
[width="35%",cols="h10,<m20",frame=topbot,options="header"]
|
||||
|===============================================
|
||||
|rc | Message components
|
||||
|0 | ?     ?     ?
|
||||
|1 | CQ     ?     ?
|
||||
|2 | CQ     ?
|
||||
|3 | MyCall     ?     ?
|
||||
|4 | MyCall     ?
|
||||
|5 | MyCall DxCall     ?
|
||||
|6 | ?     DxCall     ?
|
||||
|7 | ?     DxCall
|
||||
|8 | MyCall DxCall DxGrid
|
||||
|9 | CQ DxCall     ?
|
||||
|10 | CQ DxCall
|
||||
|11 | CQ DxCall DxGrid
|
||||
|===============================================
|
||||
@@ -1,17 +0,0 @@
|
||||
<style>
|
||||
html, body {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: Georgia, "Times New Roman", Times, serif;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: purple;
|
||||
}
|
||||
</style>
|
||||
@@ -1,77 +0,0 @@
|
||||
////
|
||||
Questions:
|
||||
Should be short one liners (in the .adoc file) ending with ?::
|
||||
If your question is too long for one line, consider multiple questions or rephrase
|
||||
|
||||
Answers:
|
||||
Can be bullet or paragraphs. Bullets make for easier reading.
|
||||
|
||||
Bullet Usage:
|
||||
* = a circle bullet single intent
|
||||
** = circle bullet double indent
|
||||
. = should be avoided as the questions are numbered
|
||||
.. = bullet a, b, c, and so on, double indent
|
||||
|
||||
Alternatives: Use a * Bullet, followed by .. for example, then have
|
||||
a multi-section answer using the * as the section header
|
||||
|
||||
* Section Header 1
|
||||
.. Possible Answer a
|
||||
.. Possible Answer b
|
||||
* Section Header 2
|
||||
.. Possible Answer a
|
||||
.. Possible Answer b
|
||||
|
||||
Link Usage:
|
||||
Use the common/links.adoc for href links to maintain consistency. Try to avoid
|
||||
apostrophes ` or ' as it breaks AsciiDoc syntax without special escaping
|
||||
and they do not translate into other languages well.
|
||||
|
||||
////
|
||||
[qanda]
|
||||
My displayed spectrum is flatter when I do not check the *Flatten* box. What's wrong?::
|
||||
|
||||
_WSJT-X_ does not expect a steep filter edge within the displayed
|
||||
passband. Use a wider IF filter or reduce the displayed passband by
|
||||
decreasing *Bins/Pixel*, increasing *Start*, or reducing the width of
|
||||
the *Wide Graph*. You might also choose to re-center the filter
|
||||
passband, if such control is available.
|
||||
|
||||
How should I configure _WSJT-X_ to run multiple instances?::
|
||||
|
||||
Start _WSJT-X_ from a command-prompt window, assigning each instance a
|
||||
unique identifier as in the following two-instance example. This
|
||||
procedure will isolate the *Settings* file and the writable file
|
||||
location for each instance of _WSJT-X_.
|
||||
|
||||
wsjtx --rig-name=TS2000
|
||||
wsjtx --rig-name=FT847
|
||||
|
||||
Rig control through _OmniRig_ seems to fail when I click *Test CAT*. What can I do about it?::
|
||||
|
||||
_Omni-Rig_ apparently has a bug that appears when you click *Test
|
||||
CAT*. Forget using *Test CAT* and just click *OK*. _Omni-Rig_ then
|
||||
behaves normally.
|
||||
|
||||
I am using _WSJT-X_ with _Ham Radio Deluxe_. All seems well until I start HRD Logbook or DM780 running in parallel; then CAT control becomes unreliable.::
|
||||
|
||||
You may see delays up to 20 seconds or so in frequency changes or
|
||||
other radio commands, due to a bug in HRD. HRD folks are aware of the
|
||||
problem, and are working to resolve it.
|
||||
|
||||
I am running _WSJT-X_ under Ubuntu. The program starts, but menu bar is missing from the top of the main window and the hot-keys don't work.::
|
||||
|
||||
Ubuntu's new "`Unity`" desktop puts the menu for the currently active
|
||||
window at the top of the primary display screen. You can restore menu
|
||||
bars to their traditional locations by typing the following in a
|
||||
command-prompt window:
|
||||
|
||||
sudo apt remove appmenu-qt5
|
||||
|
||||
+
|
||||
Alternatively, you can disable the common menu bar for just _WSJT-X_
|
||||
by starting the application with the environment variable
|
||||
QT_QPA_PLATFORMTHEME set to empty (the space after the '=' character
|
||||
is necessary):
|
||||
|
||||
QT_QPA_PLATFORMTHEME= wsjtx
|
||||
@@ -1,15 +0,0 @@
|
||||
// Status=review
|
||||
|
||||
- You can control the program's font sizes by using a text editor
|
||||
(e.g., Windows Notepad or similar) to create a one-line file named
|
||||
+fonts.txt+ in the _WSJT-X_ installation directory. Enter a single
|
||||
line of text with four numbers separated by spaces. The first two
|
||||
numbers control the font size (in points) and weight (on a 0 – 100
|
||||
scale) of most labels on the user interface. The last two numbers
|
||||
control size and weight of text in the *Band Activity* and *Rx
|
||||
Frequency* windows.
|
||||
|
||||
- By default the four numbers are "`8 50 10 50`". If you need larger
|
||||
fonts in the user interface and bold text in the decode windows, try
|
||||
something like "`10 50 12 100`" (without the quotes).
|
||||
|
||||
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 9.9 KiB |