kopia lustrzana https://gitlab.com/eliggett/wfview
Merge branch 'cluster' into shuttle
commit
5d0f6e82c5
73
CHANGELOG
73
CHANGELOG
|
@ -1,8 +1,81 @@
|
|||
# CHANGELOG
|
||||
|
||||
- 20220929
|
||||
|
||||
Fix for squished screen
|
||||
|
||||
bump version to 1.51
|
||||
|
||||
|
||||
- 20220928
|
||||
|
||||
Only request passband when there is a scope available
|
||||
|
||||
Change default passband colors.
|
||||
|
||||
Fix passband colorswatch
|
||||
|
||||
- 20220927
|
||||
|
||||
See if this works better for color pickers?
|
||||
|
||||
Ignore second VFO scope data (for now)
|
||||
|
||||
Silently ignore server audio issues if server is not enabled.
|
||||
|
||||
Always use 8bit encoding for audio device names
|
||||
|
||||
Make multimedia-plugins message only for Linux
|
||||
|
||||
- 20220926
|
||||
|
||||
Add PSK modes to IC-7610 and to passband.
|
||||
|
||||
Add passband for FM mode
|
||||
|
||||
Added click-drag tuning. Needs refinement but it's a start.
|
||||
|
||||
colorpicker: Move to 3 columns
|
||||
|
||||
First look at a passband indicator
|
||||
|
||||
- 20220925
|
||||
|
||||
Remove obsolete code
|
||||
|
||||
Remove logging of audio device realm
|
||||
|
||||
- 20220923
|
||||
|
||||
ready for v1.50
|
||||
|
||||
- 20220923
|
||||
|
||||
Delete quit confirmation checkbox
|
||||
|
||||
Use date/time for log name if none specified
|
||||
|
||||
Fix logfile/directory opening in Windows
|
||||
|
||||
Fixed glitch when tabs are changed prior to rigcaps.
|
||||
|
||||
Remove redundant CL args
|
||||
|
||||
Additional resize fixes for non-spectrum rigs.
|
||||
|
||||
Hide UI elements not needed for non-spectrum radios.
|
||||
|
||||
updated to v1.48
|
||||
|
||||
- 20220921
|
||||
|
||||
Fix that was stopping users being created when none existed
|
||||
|
||||
- 20220920
|
||||
|
||||
Added dialog box to the toFixed button where an edge can be selected.
|
||||
|
||||
Add quick fix for rigctld fmv issue
|
||||
|
||||
updated to v1.47
|
||||
|
||||
|
|
55
WHATSNEW
55
WHATSNEW
|
@ -1,44 +1,25 @@
|
|||
|
||||
The following highlights are in this 1.41-release:
|
||||
The following highlights are in this 1.51-release ince v1.50:
|
||||
|
||||
New major change is the audio transport mechanism. Lower latencies.
|
||||
About box updated to include Patreon site
|
||||
added 500 Hz step for VFO
|
||||
Added clock and UTC toggle.
|
||||
Added forced manual RTS setting
|
||||
Add RIT function and other rigctl fixes
|
||||
Adjusted window size for radios without spectrum. Thanks K5TUX.
|
||||
Allow dynamic restarting of server
|
||||
New Settings tab
|
||||
Enable High DPI Scaling
|
||||
More multi-radio support (mostly working!)
|
||||
Split LAN waterfall data for N1MM+ Spectrum Scope support: There is a combobox that allows you to select
|
||||
split/combine (or default). Split only makes sense for LAN and Combine for USB.
|
||||
added radio status display with meters for audio (speaker/mic)
|
||||
selector for audio: QT, PortAudio, RealTime audio
|
||||
version bumped to 1.4 -- rethinking of a new version schema that makes more sense
|
||||
temporary squashed logs; may redo later
|
||||
audio fixes at exit
|
||||
introduction of peak decays at the scope
|
||||
resizing of top and bottom scope/waterfall
|
||||
various fixes on the spectrum display
|
||||
+ 1.41 added color picker support for all kinds of vsual elements
|
||||
+ 1.42 added three additional second meter choices. RxAudio, TxAdio, and TxRxAudio
|
||||
+ 1.43 fixed resizing issues.
|
||||
+ 1.44 added logging window. you can send the logs to termbin.com and share the link on the forum
|
||||
+ 1.45 some more log enhancements
|
||||
moved connect button and added cancel option
|
||||
add enable/disable audioSystemServerCombo
|
||||
Fixed bug where the frequency dial skipped extra when crossing zero.
|
||||
+ 1.46 Added controls for custom scope edges, hide/show scope controls
|
||||
depending upon the scope mode the radio reports.
|
||||
Fixed clear peaks button to work with the plasma underlay.
|
||||
both audio system button are disabled when connected to radio and enabled when not.
|
||||
Remove password from log
|
||||
Fix server user handling
|
||||
+ 1.47 Added dialog box to the toFixed button where an edge can be selected.
|
||||
+ 1.51
|
||||
|
||||
|
||||
|
||||
Fix for squished screen
|
||||
Only request passband when there is a scope available
|
||||
Change default passband colors.
|
||||
Fix passband colorswatch
|
||||
Ignore second VFO scope data (for now)
|
||||
Silently ignore server audio issues if server is not enabled.
|
||||
Always use 8bit encoding for audio device names
|
||||
Make multimedia-plugins message only for Linux
|
||||
Add PSK modes to IC-7610 and to passband.
|
||||
Add passband for FM mode
|
||||
Added click-drag tuning. Needs refinement but it's a start.
|
||||
colorpicker: Move to 3 columns
|
||||
passband indicator
|
||||
Remove logging of audio device realm
|
||||
|
||||
Notes:
|
||||
|
||||
- We know about high CPU usage on RPi.
|
||||
|
|
|
@ -46,7 +46,11 @@ audioHandler::~audioHandler()
|
|||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "audio handler starting:" << setup.name;
|
||||
if (setup.port.isNull())
|
||||
{
|
||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "No audio device was found. You probably need to install libqt5multimedia-plugins.";
|
||||
#ifdef Q_OS_LINUX
|
||||
qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << "No audio device was found. You probably need to install libqt5multimedia-plugins.";
|
||||
#else
|
||||
qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << "Audio device is NULL, please check device selection in settings.";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
#include "cluster.h"
|
||||
#include "logcategories.h"
|
||||
|
||||
|
||||
dxClusterClient::dxClusterClient(QObject* parent):
|
||||
QObject(parent)
|
||||
{
|
||||
qInfo(logCluster()) << "starting dxClusterClient()";
|
||||
}
|
||||
|
||||
dxClusterClient::~dxClusterClient()
|
||||
{
|
||||
qInfo(logCluster()) << "closing dxClusterClient()";
|
||||
enableUdp(false);
|
||||
enableTcp(false);
|
||||
#ifdef USESQL
|
||||
database db;
|
||||
db.close();
|
||||
#else
|
||||
QMap<QString, spotData*>::iterator spot = allSpots.begin();
|
||||
while (spot != allSpots.end())
|
||||
{
|
||||
delete spot.value(); // Stop memory leak?
|
||||
spot = allSpots.erase(spot);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dxClusterClient::enableUdp(bool enable)
|
||||
{
|
||||
udpEnable = enable;
|
||||
if (enable)
|
||||
{
|
||||
if (udpSocket == Q_NULLPTR)
|
||||
{
|
||||
udpSocket = new QUdpSocket(this);
|
||||
bool result = udpSocket->bind(QHostAddress::AnyIPv4, udpPort);
|
||||
qInfo(logCluster()) << "Starting udpSocket() on:" << udpPort << "Result:" << result;
|
||||
|
||||
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(udpDataReceived()), Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (udpSocket != Q_NULLPTR)
|
||||
{
|
||||
qInfo(logCluster()) << "Stopping udpSocket() on:" << udpPort;
|
||||
|
||||
udpSocket->disconnect();
|
||||
delete udpSocket;
|
||||
udpSocket = Q_NULLPTR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dxClusterClient::enableTcp(bool enable)
|
||||
{
|
||||
tcpEnable = enable;
|
||||
if (enable)
|
||||
{
|
||||
tcpRegex = QRegularExpression("^DX de ([a-z|A-Z|0-9|/]+):\\s+([0-9|.]+)\\s+([a-z|A-Z|0-9|/]+)+\\s+(.*)\\s+(\\d{4}Z)");
|
||||
|
||||
if (tcpSocket == Q_NULLPTR)
|
||||
{
|
||||
tcpSocket = new QTcpSocket(this);
|
||||
tcpSocket->connectToHost(tcpServerName, tcpPort);
|
||||
qInfo(logCluster()) << "Starting tcpSocket() on:" << tcpPort;
|
||||
|
||||
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(tcpDataReceived()), Qt::QueuedConnection);
|
||||
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(tcpDisconnected()));
|
||||
|
||||
tcpCleanupTimer = new QTimer(this);
|
||||
tcpCleanupTimer->setInterval(1000 * 10); // Run once a minute
|
||||
connect(tcpCleanupTimer, SIGNAL(timeout()), this, SLOT(tcpCleanup()));
|
||||
tcpCleanupTimer->start();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tcpSocket != Q_NULLPTR)
|
||||
{
|
||||
qInfo(logCluster()) << "Disconnecting tcpSocket() on:" << tcpPort;
|
||||
if (tcpCleanupTimer != Q_NULLPTR)
|
||||
{
|
||||
tcpCleanupTimer->stop();
|
||||
delete tcpCleanupTimer;
|
||||
tcpCleanupTimer = Q_NULLPTR;
|
||||
}
|
||||
tcpSocket->disconnect();
|
||||
delete tcpSocket;
|
||||
tcpSocket = Q_NULLPTR;
|
||||
//emit deleteOldSpots(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dxClusterClient::udpDataReceived()
|
||||
{
|
||||
QHostAddress sender;
|
||||
quint16 port;
|
||||
QByteArray datagram;
|
||||
datagram.resize(udpSocket->pendingDatagramSize());
|
||||
udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &port);
|
||||
|
||||
if (udpSpotReader.setContent(datagram))
|
||||
{
|
||||
QDomElement spot = udpSpotReader.firstChildElement("spot");
|
||||
if (spot.nodeName() == "spot")
|
||||
{
|
||||
// This is a spot?
|
||||
QString action = spot.firstChildElement("action").text();
|
||||
if (action == "add") {
|
||||
spotData* data = new spotData();
|
||||
data->dxcall = spot.firstChildElement("dxcall").text();
|
||||
data->frequency = spot.firstChildElement("frequency").text().toDouble() / 1000.0;
|
||||
data->spottercall = spot.firstChildElement("spottercall").text();
|
||||
data->timestamp = QDateTime::fromString(spot.firstChildElement("timestamp").text(),"yyyy-MM-dd hh:mm:ss");
|
||||
data->mode = spot.firstChildElement("mode").text();
|
||||
data->comment = spot.firstChildElement("comment").text();
|
||||
|
||||
#ifdef USESQL
|
||||
database db = database();
|
||||
db.query(QString("DELETE from spots where dxcall='%1'").arg(data->dxcall));
|
||||
QString query = QString("INSERT INTO spots(type,spottercall,frequency,dxcall,mode,comment,timestamp) VALUES('%1','%2',%3,'%4','%5','%6','%7')\n")
|
||||
.arg("UDP").arg(data->spottercall).arg(data->frequency).arg(data->dxcall).arg(data->mode).arg(data->comment).arg(data->timestamp.toString("yyyy-MM-dd hh:mm:ss"));
|
||||
db.query(query);
|
||||
#else
|
||||
bool found = false;
|
||||
QMap<QString, spotData*>::iterator spot = allSpots.find(data->dxcall);
|
||||
while (spot != allSpots.end() && spot.key() == data->dxcall && spot.value()->frequency == data->frequency) {
|
||||
found = true;
|
||||
++spot;
|
||||
}
|
||||
if (found == false) {
|
||||
allSpots.insert(data->dxcall, data);
|
||||
}
|
||||
#endif
|
||||
emit sendOutput(QString("<spot><action>add</action><dxcall>%1</dxcall><spottercall>%2</spottercall><frequency>%3</frequency><comment>%4</comment></spot>\n")
|
||||
.arg(data->dxcall).arg(data->spottercall).arg(data->frequency).arg(data->comment));
|
||||
|
||||
}
|
||||
else if (action == "delete")
|
||||
{
|
||||
QString dxcall = spot.firstChildElement("dxcall").text();
|
||||
double frequency = spot.firstChildElement("frequency").text().toDouble() / 1000.0;
|
||||
|
||||
#ifdef USESQL
|
||||
database db = database();
|
||||
QString query=QString("DELETE from spots where dxcall='%1' AND frequency=%2").arg(dxcall).arg(frequency);
|
||||
db.query(query);
|
||||
qInfo(logCluster()) << query;
|
||||
#else
|
||||
QMap<QString, spotData*>::iterator spot = allSpots.find(dxcall);
|
||||
while (spot != allSpots.end() && spot.key() == dxcall && spot.value()->frequency == frequency)
|
||||
{
|
||||
delete spot.value(); // Stop memory leak?
|
||||
spot = allSpots.erase(spot);
|
||||
}
|
||||
#endif
|
||||
emit sendOutput(QString("<spot><action>delete</action><dxcall>%1</dxcall<frequency>%3</frequency></spot>\n")
|
||||
.arg(dxcall).arg(frequency));
|
||||
}
|
||||
updateSpots();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dxClusterClient::tcpDataReceived()
|
||||
{
|
||||
QString data = QString(tcpSocket->readAll());
|
||||
|
||||
emit sendOutput(data);
|
||||
if (data.contains("login:")) {
|
||||
sendTcpData(QString("%1\n").arg(tcpUserName));
|
||||
return;
|
||||
}
|
||||
if (data.contains("password:")) {
|
||||
sendTcpData(QString("%1\n").arg(tcpPassword));
|
||||
return;
|
||||
}
|
||||
|
||||
QRegularExpressionMatchIterator i = tcpRegex.globalMatch(data);
|
||||
while (i.hasNext()) {
|
||||
QRegularExpressionMatch match = i.next();
|
||||
if (match.hasMatch()) {
|
||||
spotData* data = new spotData();
|
||||
data->spottercall = match.captured(1);
|
||||
data->frequency = match.captured(2).toDouble() / 1000.0;
|
||||
data->dxcall = match.captured(3);
|
||||
data->comment = match.captured(4).trimmed();
|
||||
data->timestamp = QDateTime::currentDateTimeUtc();
|
||||
|
||||
#ifdef USESQL
|
||||
database db = database();
|
||||
db.query(QString("DELETE from spots where dxcall='%1'").arg(data->dxcall));
|
||||
QString query = QString("INSERT INTO spots(type,spottercall,frequency,dxcall,comment,timestamp) VALUES('%1','%2',%3,'%4','%5','%6')\n")
|
||||
.arg("TCP").arg(data->spottercall).arg(data->frequency).arg(data->dxcall).arg(data->comment).arg(data->timestamp.toString("yyyy-MM-dd hh:mm:ss"));
|
||||
db.query(query);
|
||||
#else
|
||||
bool found = false;
|
||||
QMap<QString, spotData*>::iterator spot = allSpots.find(data->dxcall);
|
||||
while (spot != allSpots.end() && spot.key() == data->dxcall && spot.value()->frequency == data->frequency) {
|
||||
found = true;
|
||||
++spot;
|
||||
}
|
||||
if (found == false) {
|
||||
allSpots.insert(data->dxcall, data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
updateSpots();
|
||||
}
|
||||
|
||||
|
||||
void dxClusterClient::sendTcpData(QString data)
|
||||
{
|
||||
qInfo(logCluster()) << "Sending:" << data;
|
||||
if (tcpSocket != Q_NULLPTR && tcpSocket->isValid() && tcpSocket->isOpen())
|
||||
{
|
||||
tcpSocket->write(data.toLatin1());
|
||||
}
|
||||
else
|
||||
{
|
||||
qInfo(logCluster()) << "socket not open!";
|
||||
}
|
||||
}
|
||||
|
||||
void dxClusterClient::tcpCleanup()
|
||||
{
|
||||
#ifdef USESQL
|
||||
database db = database();
|
||||
db.query(QString("DELETE FROM spots where timestamp < datetime('now', '-%1 minutes')").arg(tcpTimeout));
|
||||
#else
|
||||
QMap<QString, spotData*>::iterator spot = allSpots.begin();;
|
||||
while (spot != allSpots.end()) {
|
||||
if (spot.value()->timestamp.addSecs(tcpTimeout * 60) < QDateTime::currentDateTimeUtc())
|
||||
{
|
||||
delete spot.value(); // Stop memory leak?
|
||||
spot = allSpots.erase(spot);
|
||||
}
|
||||
else
|
||||
{
|
||||
++spot;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dxClusterClient::tcpDisconnected() {
|
||||
qWarning(logCluster()) << "TCP Cluster server disconnected...";
|
||||
// Need to start a timer and attempt reconnect.
|
||||
}
|
||||
|
||||
void dxClusterClient::freqRange(double low, double high)
|
||||
{
|
||||
lowFreq = low;
|
||||
highFreq = high;
|
||||
//qInfo(logCluster) << "New range" << low << "-" << high;
|
||||
updateSpots();
|
||||
}
|
||||
|
||||
void dxClusterClient::updateSpots()
|
||||
{
|
||||
QList<spotData> spots;
|
||||
#ifdef USESQL
|
||||
// Set the required frequency range.
|
||||
QString queryText = QString("SELECT * FROM spots WHERE frequency > %1 AND frequency < %2").arg(lowFreq).arg(highFreq);
|
||||
//QString queryText = QString("SELECT * FROM spots");
|
||||
database db;
|
||||
auto query = db.query(queryText);
|
||||
|
||||
while (query.next()) {
|
||||
// Step through all current spots within range
|
||||
spotData s = spotData();
|
||||
s.dxcall = query.value(query.record().indexOf("dxcall")).toString();
|
||||
s.frequency = query.value(query.record().indexOf("frequency")).toDouble();
|
||||
spots.append(s);
|
||||
}
|
||||
#else
|
||||
QMap<QString, spotData*>::iterator spot = allSpots.begin();;
|
||||
while (spot != allSpots.end()) {
|
||||
if (spot.value()->frequency > lowFreq && spot.value()->frequency < highFreq)
|
||||
{
|
||||
spots.append(**spot);
|
||||
}
|
||||
++spot;
|
||||
}
|
||||
|
||||
#endif
|
||||
emit sendSpots(spots);
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
#ifndef CLUSTER_H
|
||||
#define CLUSTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QUdpSocket>
|
||||
#include <QTcpSocket>
|
||||
#include <QDomDocument>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#include <QDateTime>
|
||||
#include <QRegularExpression>
|
||||
#include <QTimer>
|
||||
|
||||
#ifdef USESQL
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#endif
|
||||
|
||||
#include <qcustomplot.h>
|
||||
|
||||
#ifdef USESQL
|
||||
#include "database.h"
|
||||
#endif
|
||||
|
||||
struct spotData {
|
||||
QString dxcall;
|
||||
double frequency;
|
||||
QString spottercall;
|
||||
QDateTime timestamp;
|
||||
QString mode;
|
||||
QString comment;
|
||||
QCPItemText* text = Q_NULLPTR;
|
||||
bool current = false;
|
||||
};
|
||||
|
||||
struct clusterSettings {
|
||||
QString server;
|
||||
int port=7300;
|
||||
QString userName;
|
||||
QString password;
|
||||
int timeout=30;
|
||||
bool isdefault;
|
||||
};
|
||||
|
||||
class dxClusterClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit dxClusterClient(QObject* parent = nullptr);
|
||||
virtual ~dxClusterClient();
|
||||
|
||||
signals:
|
||||
void addSpot(spotData* spot);
|
||||
void deleteSpot(QString dxcall);
|
||||
void deleteOldSpots(int minutes);
|
||||
void sendOutput(QString text);
|
||||
void sendSpots(QList<spotData> spots);
|
||||
|
||||
public slots:
|
||||
void udpDataReceived();
|
||||
void tcpDataReceived();
|
||||
void tcpDisconnected();
|
||||
void enableUdp(bool enable);
|
||||
void enableTcp(bool enable);
|
||||
void setUdpPort(int p) { udpPort = p; }
|
||||
void setTcpServerName(QString s) { tcpServerName = s; }
|
||||
void setTcpPort(int p) { tcpPort = p; }
|
||||
void setTcpUserName(QString s) { tcpUserName = s; }
|
||||
void setTcpPassword(QString s) { tcpPassword = s; }
|
||||
void setTcpTimeout(int p) { tcpTimeout = p; }
|
||||
void tcpCleanup();
|
||||
void freqRange(double low, double high);
|
||||
|
||||
private:
|
||||
void sendTcpData(QString data);
|
||||
bool databaseOpen();
|
||||
void updateSpots();
|
||||
|
||||
bool udpEnable;
|
||||
bool tcpEnable;
|
||||
QUdpSocket* udpSocket=Q_NULLPTR;
|
||||
QTcpSocket* tcpSocket=Q_NULLPTR;
|
||||
int udpPort;
|
||||
QString tcpServerName;
|
||||
int tcpPort;
|
||||
QString tcpUserName;
|
||||
QString tcpPassword;
|
||||
int tcpTimeout;
|
||||
QDomDocument udpSpotReader;
|
||||
QRegularExpression tcpRegex;
|
||||
QMutex mutex;
|
||||
bool authenticated=false;
|
||||
QTimer* tcpCleanupTimer=Q_NULLPTR;
|
||||
#ifdef USESQL
|
||||
QSqlDatabase db;
|
||||
#endif
|
||||
double lowFreq;
|
||||
double highFreq;
|
||||
QMap<QString,spotData*> allSpots;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -18,6 +18,7 @@ struct colorPrefsType{
|
|||
QColor underlayFill;
|
||||
QColor plotBackground;
|
||||
QColor tuningLine;
|
||||
QColor passband;
|
||||
|
||||
// Waterfall:
|
||||
QColor wfBackground;
|
||||
|
@ -32,6 +33,10 @@ struct colorPrefsType{
|
|||
QColor meterPeakScale;
|
||||
QColor meterLowerLine;
|
||||
QColor meterLowText;
|
||||
|
||||
// Assorted
|
||||
QColor clusterSpots;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
#ifdef USESQL
|
||||
|
||||
#include "database.h"
|
||||
#include "logcategories.h"
|
||||
|
||||
database::database()
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
database::~database()
|
||||
{
|
||||
}
|
||||
|
||||
bool database::open()
|
||||
{
|
||||
auto name = "my_db_" + QString::number((quint64)QThread::currentThread(), 16);
|
||||
if (QSqlDatabase::contains(name))
|
||||
{
|
||||
db = QSqlDatabase::database(name);
|
||||
qu = QSqlQuery(db);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qInfo(logCluster()) << "Creating new connection" << name;
|
||||
db = QSqlDatabase::addDatabase("QSQLITE", name);
|
||||
qu = QSqlQuery(db);
|
||||
}
|
||||
|
||||
//QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/" + "wfview.db";
|
||||
QString path = ":memory:";
|
||||
qInfo(logCluster()) << "DB Filename" << path;
|
||||
db.setDatabaseName(path);
|
||||
if (db.isValid())
|
||||
{
|
||||
db.open();
|
||||
if (check()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
qWarning(logCluster()) << "Database is not valid!";
|
||||
return false;
|
||||
}
|
||||
|
||||
void database::close()
|
||||
{
|
||||
auto name = "my_db_" + QString::number((quint64)QThread::currentThread(), 16);
|
||||
qInfo(logCluster()) << "Closing database connection:" << name;
|
||||
db.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QSqlQuery database::query(QString query)
|
||||
{
|
||||
if (!db.isOpen())
|
||||
{
|
||||
qWarning(logCluster()) << "Query Database is not open!";
|
||||
db.open();
|
||||
}
|
||||
qu.exec(query);
|
||||
return qu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool database::check()
|
||||
{
|
||||
if (db.isOpen()) {
|
||||
for (const auto& table : db.tables())
|
||||
{
|
||||
if (table == "spots")
|
||||
{
|
||||
qInfo(logCluster()) << "DB Contains spots table";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
qInfo(logCluster()) << "Creating spots table";
|
||||
// Spots table does not exist, need to create it.
|
||||
/*
|
||||
QString dxcall;
|
||||
double frequency;
|
||||
QString spottercall;
|
||||
QDateTime timestamp;
|
||||
QString mode;
|
||||
QString comment;
|
||||
QCPItemText* text = Q_NULLPTR;*/
|
||||
qu.exec("CREATE TABLE spots "
|
||||
"(id INTEGER PRIMARY KEY, "
|
||||
"type VARCHAR(3),"
|
||||
"dxcall VARCHAR(30),"
|
||||
"spottercall VARCHAR(30),"
|
||||
"frequency DOUBLE,"
|
||||
"timestamp DATETIME,"
|
||||
"mode VARCHAR(30),"
|
||||
"comment VARCHAR(255) )");
|
||||
qu.exec("CREATE INDEX spots_index ON spots(type,dxcall,frequency,timestamp)");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qWarning(logCluster()) << "Database is not open";
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
#ifdef USESQL
|
||||
|
||||
#ifndef DATABASE_H
|
||||
#define DATABASE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
#include <QThread>
|
||||
#include <QStandardPaths>
|
||||
|
||||
class database
|
||||
{
|
||||
public:
|
||||
explicit database();
|
||||
virtual ~database();
|
||||
bool open();
|
||||
void close();
|
||||
QSqlQuery query(QString query);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
private:
|
||||
bool check();
|
||||
QSqlDatabase db;
|
||||
QSqlQuery qu;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -17,6 +17,8 @@ enum mode_kind {
|
|||
modeFM=0x05,
|
||||
modeCW_R=0x07,
|
||||
modeRTTY_R=0x08,
|
||||
modePSK = 0x12,
|
||||
modePSK_R = 0x13,
|
||||
modeLSB_D=0x80,
|
||||
modeUSB_D=0x81,
|
||||
modeDV=0x17,
|
||||
|
@ -29,9 +31,7 @@ enum mode_kind {
|
|||
modedPMR,
|
||||
modeNXDN_VN,
|
||||
modeNXDN_N,
|
||||
modeDCR,
|
||||
modePSK,
|
||||
modePSK_R
|
||||
modeDCR
|
||||
};
|
||||
|
||||
struct mode_info {
|
||||
|
|
|
@ -13,3 +13,4 @@ Q_LOGGING_CATEGORY(logRigCtlD, "rigctld")
|
|||
Q_LOGGING_CATEGORY(logTcpServer, "tcpserver")
|
||||
Q_LOGGING_CATEGORY(logUsbControl, "usbcontrol")
|
||||
Q_LOGGING_CATEGORY(logAudioConverter, "audioconverter")
|
||||
Q_LOGGING_CATEGORY(logCluster, "cluster")
|
||||
|
|
|
@ -16,6 +16,7 @@ Q_DECLARE_LOGGING_CATEGORY(logRigCtlD)
|
|||
Q_DECLARE_LOGGING_CATEGORY(logTcpServer)
|
||||
Q_DECLARE_LOGGING_CATEGORY(logUsbControl)
|
||||
Q_DECLARE_LOGGING_CATEGORY(logAudioConverter)
|
||||
Q_DECLARE_LOGGING_CATEGORY(logCluster)
|
||||
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(__PRETTY_FUNCTION__)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "loggingwindow.h"
|
||||
#include "ui_loggingwindow.h"
|
||||
|
||||
loggingWindow::loggingWindow(QWidget *parent) :
|
||||
loggingWindow::loggingWindow(QString logFilename, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::loggingWindow)
|
||||
ui(new Ui::loggingWindow),
|
||||
logFilename(logFilename)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setWindowTitle("Log");
|
||||
|
@ -12,20 +13,15 @@ loggingWindow::loggingWindow(QWidget *parent) :
|
|||
ui->annotateBtn->setDefault(true);
|
||||
ui->logTextDisplay->setFocusPolicy(Qt::NoFocus);
|
||||
ui->annotateBtn->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
QDir d = QFileInfo(logFilename).absoluteDir();
|
||||
logDirectory = d.absolutePath();
|
||||
|
||||
QFont font("Monospace");
|
||||
font.setStyleHint(QFont::TypeWriter);
|
||||
ui->logTextDisplay->setFont(font);
|
||||
ui->userAnnotationText->setFont(font);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
logFilename = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation)[0] + "/wfview.log";
|
||||
logDirectory = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation)[0];
|
||||
|
||||
#else
|
||||
logFilename= QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0] + "/wfview.log";
|
||||
logDirectory = QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0];
|
||||
#endif
|
||||
clipboard = QApplication::clipboard();
|
||||
socket = new QTcpSocket(this);
|
||||
connect(socket, SIGNAL(connected()), this, SLOT(connectedToHost()));
|
||||
|
@ -142,37 +138,39 @@ void loggingWindow::on_clearDisplayBtn_clicked()
|
|||
void loggingWindow::on_openDirBtn_clicked()
|
||||
{
|
||||
QString cmd;
|
||||
int rtnval = 0;
|
||||
#ifdef Q_OS_MAC
|
||||
cmd = "open " + logDirectory;
|
||||
#endif
|
||||
bool rtn = false;
|
||||
QStringList arg;
|
||||
const QFileInfo dir(logDirectory);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
cmd = "xdg-open " + logDirectory;
|
||||
cmd = "xdg-open";
|
||||
#elif defined(Q_OS_WIN)
|
||||
cmd = QStandardPaths::findExecutable("explorer.exe");
|
||||
if (!dir.isDir())
|
||||
arg += QLatin1String("/select,");
|
||||
#else
|
||||
cmd = "open";
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
cmd = "start " + logDirectory;
|
||||
#endif
|
||||
rtnval = system(cmd.toLocal8Bit().data());
|
||||
if(rtnval)
|
||||
qInfo(logLogger()) << "Error, open log directory command returned error code " << rtnval;
|
||||
arg += QDir::toNativeSeparators(dir.canonicalFilePath());;
|
||||
rtn = QProcess::startDetached(cmd, arg);
|
||||
if(!rtn)
|
||||
qInfo(logLogger()) << "Error, open log directory" << logDirectory << "command failed";
|
||||
}
|
||||
|
||||
void loggingWindow::on_openLogFileBtn_clicked()
|
||||
{
|
||||
QString cmd;
|
||||
int rtnval = 0;
|
||||
#ifdef Q_OS_MAC
|
||||
cmd = "open " + logFilename;
|
||||
#endif
|
||||
bool rtn = false;
|
||||
#ifdef Q_OS_LINUX
|
||||
cmd = "xdg-open " + logFilename;
|
||||
cmd = "xdg-open";
|
||||
#elif defined(Q_OS_WIN)
|
||||
cmd = QStandardPaths::findExecutable("notepad.exe");
|
||||
#else
|
||||
cmd = "open";
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
cmd = "notepad " + logFilename;
|
||||
#endif
|
||||
rtnval = system(cmd.toLocal8Bit().data());
|
||||
if(rtnval)
|
||||
qInfo(logLogger()) << "Error, open log file command returned error code " << rtnval;
|
||||
rtn = QProcess::startDetached(cmd, { logFilename });
|
||||
if(!rtn)
|
||||
qInfo(logLogger()) << "Error, open log file command failed";
|
||||
}
|
||||
|
||||
void loggingWindow::on_sendToPasteBtn_clicked()
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <QTextStream>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include <QProcess>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
#include "logcategories.h"
|
||||
|
||||
|
@ -22,7 +25,7 @@ class loggingWindow : public QWidget
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit loggingWindow(QWidget *parent = nullptr);
|
||||
explicit loggingWindow(QString logFilename, QWidget *parent = 0);
|
||||
~loggingWindow();
|
||||
void acceptLogText(QString text);
|
||||
|
||||
|
@ -57,14 +60,14 @@ signals:
|
|||
void setDebugMode(bool debugOn);
|
||||
|
||||
private:
|
||||
Ui::loggingWindow *ui;
|
||||
Ui::loggingWindow* ui;
|
||||
QString logFilename;
|
||||
QString logDirectory;
|
||||
QClipboard *clipboard;
|
||||
QMessageBox URLmsgBox;
|
||||
QScrollBar *vertLogScroll;
|
||||
QScrollBar *horizLogScroll;
|
||||
QMutex textMutex;
|
||||
QString logFilename;
|
||||
QString logDirectory;
|
||||
QTcpSocket *socket;
|
||||
void sendToTermbin();
|
||||
};
|
||||
|
|
48
main.cpp
48
main.cpp
|
@ -71,19 +71,15 @@ int main(int argc, char *argv[])
|
|||
//debugMode = true;
|
||||
#endif
|
||||
|
||||
QString serialPortCL;
|
||||
QString hostCL;
|
||||
QString civCL;
|
||||
#ifdef Q_OS_MAC
|
||||
QString logFilename= QStandardPaths::standardLocations(QStandardPaths::DownloadLocation)[0] + "/wfview.log";
|
||||
#else
|
||||
QString logFilename= QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0] + "/wfview.log";
|
||||
#endif
|
||||
QDateTime date = QDateTime::currentDateTime();
|
||||
QString formattedTime = date.toString("dd.MM.yyyy hh:mm:ss");
|
||||
QString logFilename = (QString("%1/%2-%3.log").arg(QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0]).arg(a.applicationName()).arg(date.toString("yyyyMMddhhmmss")));
|
||||
|
||||
QString settingsFile = NULL;
|
||||
QString currentArg;
|
||||
|
||||
|
||||
const QString helpText = QString("\nUsage: -p --port /dev/port, -h --host remotehostname, -c --civ 0xAddr, -l --logfile filename.log, -s --settings filename.ini, -d --debug, -v --version\n"); // TODO...
|
||||
const QString helpText = QString("\nUsage: -l --logfile filename.log, -s --settings filename.ini, -d --debug, -v --version\n"); // TODO...
|
||||
#ifdef BUILD_WFSERVER
|
||||
const QString version = QString("wfserver version: %1 (Git:%2 on %3 at %4 by %5@%6)\nOperating System: %7 (%8)\nBuild Qt Version %9. Current Qt Version: %10\n")
|
||||
.arg(QString(WFVIEW_VERSION))
|
||||
|
@ -102,34 +98,10 @@ int main(int argc, char *argv[])
|
|||
//qInfo() << "Argc: " << c << " argument: " << argv[c];
|
||||
currentArg = QString(argv[c]);
|
||||
|
||||
if ((currentArg == "-p") || (currentArg == "--port"))
|
||||
{
|
||||
if (argc > c)
|
||||
{
|
||||
serialPortCL = argv[c + 1];
|
||||
c += 1;
|
||||
}
|
||||
}
|
||||
else if ((currentArg == "-d") || (currentArg == "--debug"))
|
||||
if ((currentArg == "-d") || (currentArg == "--debug"))
|
||||
{
|
||||
debugMode = true;
|
||||
}
|
||||
else if ((currentArg == "-h") || (currentArg == "--host"))
|
||||
{
|
||||
if(argc > c)
|
||||
{
|
||||
hostCL = argv[c+1];
|
||||
c+=1;
|
||||
}
|
||||
}
|
||||
else if ((currentArg == "-c") || (currentArg == "--civ"))
|
||||
{
|
||||
if (argc > c)
|
||||
{
|
||||
civCL = argv[c + 1];
|
||||
c += 1;
|
||||
}
|
||||
}
|
||||
else if ((currentArg == "-l") || (currentArg == "--logfile"))
|
||||
{
|
||||
if (argc > c)
|
||||
|
@ -173,9 +145,7 @@ int main(int argc, char *argv[])
|
|||
qInstallMessageHandler(messageHandler);
|
||||
|
||||
qInfo(logSystem()) << version;
|
||||
qDebug(logSystem()) << QString("SerialPortCL as set by parser: %1").arg(serialPortCL);
|
||||
qDebug(logSystem()) << QString("remote host as set by parser: %1").arg(hostCL);
|
||||
qDebug(logSystem()) << QString("CIV as set by parser: %1").arg(civCL);
|
||||
|
||||
#endif
|
||||
#ifdef BUILD_WFSERVER
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -185,10 +155,10 @@ int main(int argc, char *argv[])
|
|||
signal(SIGTERM, cleanup);
|
||||
signal(SIGKILL, cleanup);
|
||||
#endif
|
||||
w = new servermain(serialPortCL, hostCL, settingsFile);
|
||||
w = new servermain(logFilename, settingsFile);
|
||||
#else
|
||||
a.setWheelScrollLines(1); // one line per wheel click
|
||||
wfmain w(serialPortCL, hostCL, settingsFile, debugMode);
|
||||
wfmain w(settingsFile, logFilename, debugMode);
|
||||
w.show();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -872,6 +872,13 @@ void rigCommander::getDuplexMode()
|
|||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::getPassband()
|
||||
{
|
||||
QByteArray payload;
|
||||
payload.setRawData("\x1A\x03", 2);
|
||||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::getTransmitFrequency()
|
||||
{
|
||||
QByteArray payload;
|
||||
|
@ -2511,6 +2518,9 @@ void rigCommander::parseRegisters1A()
|
|||
// band stacking register
|
||||
parseBandStackReg();
|
||||
break;
|
||||
case '\x03':
|
||||
emit havePassband(bcdHexToUChar((quint8)payloadIn[2]));
|
||||
break;
|
||||
case '\x04':
|
||||
state.set(AGC, (quint8)payloadIn[2], false);
|
||||
break;
|
||||
|
@ -3239,8 +3249,8 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.bands.push_back(bandGen);
|
||||
rigCaps.bsr[bandGen] = 0x11;
|
||||
rigCaps.modes = commonModes;
|
||||
rigCaps.modes.insert(rigCaps.modes.end(), {createMode(modePSK, 0x12, "PSK"),
|
||||
createMode(modePSK_R, 0x13, "PSK-R")});
|
||||
rigCaps.modes.insert(rigCaps.modes.end(), { createMode(modePSK, 0x12, "PSK"),
|
||||
createMode(modePSK_R, 0x13, "PSK-R") });
|
||||
rigCaps.transceiveCommand = QByteArrayLiteral("\x1a\x05\x00\x97");
|
||||
break;
|
||||
case model7610:
|
||||
|
@ -3273,6 +3283,8 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.bands.push_back(band630m);
|
||||
rigCaps.bands.push_back(band2200m);
|
||||
rigCaps.modes = commonModes;
|
||||
rigCaps.modes.insert(rigCaps.modes.end(), { createMode(modePSK, 0x12, "PSK"),
|
||||
createMode(modePSK_R, 0x13, "PSK-R") });
|
||||
rigCaps.hasRXAntenna = true;
|
||||
rigCaps.transceiveCommand = QByteArrayLiteral("\x1a\x05\x01\x12");
|
||||
break;
|
||||
|
@ -3771,9 +3783,16 @@ void rigCommander::parseSpectrum()
|
|||
freqt fStart;
|
||||
freqt fEnd;
|
||||
|
||||
unsigned char vfo = bcdHexToUChar(payloadIn[02]);
|
||||
unsigned char sequence = bcdHexToUChar(payloadIn[03]);
|
||||
|
||||
//unsigned char sequenceMax = bcdHexToDecimal(payloadIn[04]);
|
||||
|
||||
if (vfo == 1)
|
||||
{
|
||||
// This is for the second VFO!
|
||||
return;
|
||||
}
|
||||
|
||||
// unsigned char waveInfo = payloadIn[06]; // really just one byte?
|
||||
//qInfo(logRig()) << "Spectrum Data received: " << sequence << "/" << sequenceMax << " mode: " << scopeMode << " waveInfo: " << waveInfo << " length: " << payloadIn.length();
|
||||
|
|
|
@ -157,6 +157,8 @@ public slots:
|
|||
void setManualNotch(bool enabled);
|
||||
void getManualNotch();
|
||||
|
||||
void getPassband();
|
||||
|
||||
// Repeater:
|
||||
void setDuplexMode(duplexMode dm);
|
||||
void getDuplexMode();
|
||||
|
@ -321,6 +323,7 @@ signals:
|
|||
void haveBandStackReg(freqt f, char mode, char filter, bool dataOn);
|
||||
void haveRitEnabled(bool ritEnabled);
|
||||
void haveRitFrequency(int ritHz);
|
||||
void havePassband(quint8 pass);
|
||||
|
||||
// Repeater:
|
||||
void haveDuplexMode(duplexMode);
|
||||
|
|
|
@ -107,7 +107,7 @@ struct rigCapabilities {
|
|||
|
||||
QVector<rigInput> inputs;
|
||||
|
||||
bool hasSpectrum;
|
||||
bool hasSpectrum=true;
|
||||
quint8 spectSeqMax;
|
||||
quint16 spectAmpMax;
|
||||
quint16 spectLenMax;
|
||||
|
|
|
@ -8,10 +8,8 @@
|
|||
// This code is copyright 2017-2020 Elliott H. Liggett
|
||||
// All rights reserved
|
||||
|
||||
servermain::servermain(const QString serialPortCL, const QString hostCL, const QString settingsFile)
|
||||
servermain::servermain(const QString settingsFile, const QString logFile)
|
||||
{
|
||||
this->serialPortCL = serialPortCL;
|
||||
this->hostCL = hostCL;
|
||||
|
||||
qRegisterMetaType <udpPreferences>(); // Needs to be registered early.
|
||||
qRegisterMetaType <rigCapabilities>();
|
||||
|
|
|
@ -46,9 +46,7 @@ class servermain : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
servermain(const QString serialPortCL, const QString hostCL, const QString settingsFile);
|
||||
QString serialPortCL;
|
||||
QString hostCL;
|
||||
servermain(const QString logFile, const QString settingsFile);
|
||||
~servermain();
|
||||
|
||||
signals:
|
||||
|
|
850
wfmain.cpp
850
wfmain.cpp
Plik diff jest za duży
Load Diff
75
wfmain.h
75
wfmain.h
|
@ -40,6 +40,7 @@
|
|||
#include "selectradio.h"
|
||||
#include "colorprefs.h"
|
||||
#include "loggingwindow.h"
|
||||
#include "cluster.h"
|
||||
|
||||
#include <qcustomplot.h>
|
||||
#include <qserialportinfo.h>
|
||||
|
@ -67,9 +68,7 @@ class wfmain : public QMainWindow
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit wfmain(const QString serialPortCL, const QString hostCL, const QString settingsFile, bool debugMode, QWidget *parent = 0);
|
||||
QString serialPortCL;
|
||||
QString hostCL;
|
||||
explicit wfmain(const QString settingsFile, const QString logFile, bool debugMode, QWidget *parent = 0);
|
||||
~wfmain();
|
||||
static void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
|
||||
void handleLogText(QString text);
|
||||
|
@ -80,7 +79,7 @@ signals:
|
|||
void setRigID(unsigned char rigID);
|
||||
void setRTSforPTT(bool enabled);
|
||||
|
||||
// Power
|
||||
|
||||
void sendPowerOn();
|
||||
void sendPowerOff();
|
||||
|
||||
|
@ -103,6 +102,7 @@ signals:
|
|||
|
||||
// Repeater:
|
||||
void getDuplexMode();
|
||||
void getPassband();
|
||||
void getTone();
|
||||
void getTSQL();
|
||||
void getDTCS();
|
||||
|
@ -196,7 +196,16 @@ signals:
|
|||
void shuttleLed(bool, unsigned char);
|
||||
void sendUsbControllerCommands(QVector<COMMAND>* cmds);
|
||||
void sendUsbControllerButtons(QVector<BUTTON>* buts);
|
||||
|
||||
void setClusterUdpPort(int port);
|
||||
void setClusterEnableUdp(bool udp);
|
||||
void setClusterEnableTcp(bool tcp);
|
||||
void setClusterServerName(QString name);
|
||||
void setClusterTcpPort(int port);
|
||||
void setClusterUserName(QString name);
|
||||
void setClusterPassword(QString pass);
|
||||
void setClusterTimeout(int timeout);
|
||||
void setFrequencyRange(double low, double high);
|
||||
|
||||
private slots:
|
||||
void updateSizes(int tabIndex);
|
||||
void shortcutF1();
|
||||
|
@ -252,7 +261,7 @@ private slots:
|
|||
void receiveRITValue(int ritValHz);
|
||||
void receiveModInput(rigInput input, bool dataOn);
|
||||
//void receiveDuplexMode(duplexMode dm);
|
||||
|
||||
void receivePassband(quint8 pass);
|
||||
|
||||
|
||||
// Levels:
|
||||
|
@ -295,6 +304,8 @@ private slots:
|
|||
void receiveStatusUpdate(networkStatus status);
|
||||
void receiveNetworkAudioLevels(networkAudioLevels l);
|
||||
void handlePlotClick(QMouseEvent *);
|
||||
void handlePlotMouseRelease(QMouseEvent *);
|
||||
void handlePlotMouseMove(QMouseEvent *);
|
||||
void handlePlotDoubleClick(QMouseEvent *);
|
||||
void handleWFClick(QMouseEvent *);
|
||||
void handleWFDoubleClick(QMouseEvent *);
|
||||
|
@ -632,6 +643,10 @@ private slots:
|
|||
|
||||
void on_colorEditTuningLine_editingFinished();
|
||||
|
||||
void on_colorSetBtnPassband_clicked();
|
||||
|
||||
void on_colorEditPassband_editingFinished();
|
||||
|
||||
void on_colorSetBtnMeterLevel_clicked();
|
||||
|
||||
void on_colorEditMeterLevel_editingFinished();
|
||||
|
@ -648,6 +663,10 @@ private slots:
|
|||
|
||||
void on_colorEditMeterText_editingFinished();
|
||||
|
||||
void on_colorSetBtnClusterSpots_clicked();
|
||||
|
||||
void on_colorEditClusterSpots_editingFinished();
|
||||
|
||||
void on_colorRenamePresetBtn_clicked();
|
||||
|
||||
void on_colorRevertPresetBtn_clicked();
|
||||
|
@ -668,9 +687,26 @@ private slots:
|
|||
|
||||
void on_customEdgeBtn_clicked();
|
||||
|
||||
void on_clusterUdpEnable_clicked(bool enable);
|
||||
void on_clusterTcpEnable_clicked(bool enable);
|
||||
void on_clusterUdpPortLineEdit_editingFinished();
|
||||
void on_clusterServerNameCombo_currentTextChanged(QString text);
|
||||
void on_clusterServerNameCombo_currentIndexChanged(int index);
|
||||
void on_clusterTcpPortLineEdit_editingFinished();
|
||||
void on_clusterUsernameLineEdit_editingFinished();
|
||||
void on_clusterPasswordLineEdit_editingFinished();
|
||||
void on_clusterTimeoutLineEdit_editingFinished();
|
||||
void on_clusterPopOutBtn_clicked();
|
||||
|
||||
void on_clickDragTuningEnableChk_clicked(bool checked);
|
||||
|
||||
void receiveClusterOutput(QString text);
|
||||
void receiveSpots(QList<spotData> spots);
|
||||
|
||||
private:
|
||||
Ui::wfmain *ui;
|
||||
void closeEvent(QCloseEvent *event);
|
||||
QString logFilename;
|
||||
bool debugMode;
|
||||
QString version;
|
||||
QSettings *settings=Q_NULLPTR;
|
||||
|
@ -683,11 +719,11 @@ private:
|
|||
void initLogging();
|
||||
QTimer logCheckingTimer;
|
||||
int logCheckingOldPosition = 0;
|
||||
QString logFilename;
|
||||
|
||||
QCustomPlot *plot; // line plot
|
||||
QCustomPlot *wf; // waterfall image
|
||||
QCPItemLine * freqIndicatorLine;
|
||||
QCPItemRect* passbandIndicator;
|
||||
void setAppTheme(bool isCustom);
|
||||
void prepareWf();
|
||||
void prepareWf(unsigned int wfLength);
|
||||
|
@ -803,6 +839,10 @@ private:
|
|||
double wfCeiling = 160;
|
||||
double oldPlotFloor = -1;
|
||||
double oldPlotCeiling = 999;
|
||||
double passBand = 0.0;
|
||||
|
||||
double mousePressFreq = 0.0;
|
||||
double mouseReleaseFreq = 0.0;
|
||||
|
||||
QVector <QByteArray> wfimage;
|
||||
unsigned int wfLengthMax;
|
||||
|
@ -825,7 +865,7 @@ private:
|
|||
cmdGetDataMode, cmdSetModeFilter, cmdSetDataModeOn, cmdSetDataModeOff, cmdGetRitEnabled, cmdGetRitValue,
|
||||
cmdSpecOn, cmdSpecOff, cmdDispEnable, cmdDispDisable, cmdGetRxGain, cmdSetRxRfGain, cmdGetAfGain, cmdSetAfGain,
|
||||
cmdGetSql, cmdSetSql, cmdGetIFShift, cmdSetIFShift, cmdGetTPBFInner, cmdSetTPBFInner,
|
||||
cmdGetTPBFOuter, cmdSetTPBFOuter, cmdGetATUStatus,
|
||||
cmdGetTPBFOuter, cmdSetTPBFOuter, cmdGetATUStatus, cmdGetPassband,
|
||||
cmdSetATU, cmdStartATU, cmdGetSpectrumMode,
|
||||
cmdGetSpectrumSpan, cmdScopeCenterMode, cmdScopeFixedMode, cmdGetPTT, cmdSetPTT,cmdPTTToggle,
|
||||
cmdGetTxPower, cmdSetTxPower, cmdGetMicGain, cmdSetMicGain, cmdSetModLevel,
|
||||
|
@ -918,6 +958,14 @@ private:
|
|||
quint16 tcpPort;
|
||||
quint8 waterfallFormat;
|
||||
audioType audioSystem;
|
||||
bool clusterUdpEnable;
|
||||
bool clusterTcpEnable;
|
||||
int clusterUdpPort;
|
||||
QString clusterTcpServerName;
|
||||
QString clusterTcpUserName;
|
||||
QString clusterTcpPassword;
|
||||
int clusterTimeout;
|
||||
bool clickDragTuningEnable;
|
||||
} prefs;
|
||||
|
||||
preferences defPrefs;
|
||||
|
@ -1063,6 +1111,14 @@ private:
|
|||
QVector<COMMAND> usbCommands;
|
||||
QVector<BUTTON> usbButtons;
|
||||
|
||||
dxClusterClient* cluster = Q_NULLPTR;
|
||||
QThread* clusterThread = Q_NULLPTR;
|
||||
QMap<QString, spotData*> clusterSpots;
|
||||
QTimer clusterTimer;
|
||||
QCPItemText* text=Q_NULLPTR;
|
||||
QList<clusterSettings> clusters;
|
||||
QMutex clusterMutex;
|
||||
QColor clusterColor;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(struct rigCapabilities)
|
||||
|
@ -1076,10 +1132,13 @@ Q_DECLARE_METATYPE(struct timekind)
|
|||
Q_DECLARE_METATYPE(struct datekind)
|
||||
Q_DECLARE_METATYPE(struct networkStatus)
|
||||
Q_DECLARE_METATYPE(struct networkAudioLevels)
|
||||
Q_DECLARE_METATYPE(struct spotData)
|
||||
Q_DECLARE_METATYPE(enum rigInput)
|
||||
Q_DECLARE_METATYPE(enum meterKind)
|
||||
Q_DECLARE_METATYPE(enum spectrumMode)
|
||||
Q_DECLARE_METATYPE(enum mode_kind)
|
||||
Q_DECLARE_METATYPE(QList<radio_cap_packet>)
|
||||
Q_DECLARE_METATYPE(QList<spotData>)
|
||||
Q_DECLARE_METATYPE(rigstate*)
|
||||
Q_DECLARE_METATYPE(QVector <BUTTON>*)
|
||||
Q_DECLARE_METATYPE(struct BUTTON*)
|
||||
|
|
|
@ -13,7 +13,7 @@ TEMPLATE = app
|
|||
|
||||
CONFIG += console
|
||||
|
||||
DEFINES += WFVIEW_VERSION=\\\"1.46\\\"
|
||||
DEFINES += WFVIEW_VERSION=\\\"1.51\\\"
|
||||
|
||||
DEFINES += BUILD_WFSERVER
|
||||
|
||||
|
|
11
wfview.pro
11
wfview.pro
|
@ -4,14 +4,17 @@
|
|||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui serialport network multimedia
|
||||
QT += core gui serialport network multimedia xml
|
||||
|
||||
#QT += sql
|
||||
#DEFINES += USESQL
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||
|
||||
TARGET = wfview
|
||||
TEMPLATE = app
|
||||
|
||||
DEFINES += WFVIEW_VERSION=\\\"1.46\\\"
|
||||
DEFINES += WFVIEW_VERSION=\\\"1.51\\\"
|
||||
|
||||
DEFINES += BUILD_WFVIEW
|
||||
|
||||
|
@ -182,6 +185,8 @@ SOURCES += main.cpp\
|
|||
transceiveradjustments.cpp \
|
||||
selectradio.cpp \
|
||||
tcpserver.cpp \
|
||||
cluster.cpp \
|
||||
database.cpp \
|
||||
aboutbox.cpp
|
||||
|
||||
HEADERS += wfmain.h \
|
||||
|
@ -220,6 +225,8 @@ HEADERS += wfmain.h \
|
|||
audiotaper.h \
|
||||
selectradio.h \
|
||||
tcpserver.h \
|
||||
cluster.h \
|
||||
database.h \
|
||||
aboutbox.h
|
||||
|
||||
FORMS += wfmain.ui \
|
||||
|
|
Ładowanie…
Reference in New Issue