kopia lustrzana https://gitlab.com/eliggett/wfview
Merge branch 'master' into opus
commit
bc0d69ffb5
210
CHANGELOG
210
CHANGELOG
|
@ -1,8 +1,218 @@
|
|||
# CHANGELOG
|
||||
|
||||
- 20210724
|
||||
|
||||
small changes to INSTAll.md and addition of mint 20.2/openSUSE 15.3
|
||||
|
||||
- 20210720
|
||||
|
||||
Clear out meter values when type is switched.
|
||||
|
||||
Allow user to turn off power-down confirmation msgbox
|
||||
|
||||
- 20210719
|
||||
|
||||
wfview now uses the meter's own balistics (average and peak code). This
|
||||
makes it very easy to meter any parameter 0-255. Meter Type "meterNone"
|
||||
or other will display data in "raw" format.
|
||||
|
||||
- 20210718
|
||||
|
||||
Added center tuning for IC-R8600, partially moved meter balistics
|
||||
(average and peak) to the meter class.
|
||||
|
||||
Quick debug for the metering queue, just in case.
|
||||
|
||||
20210717
|
||||
|
||||
Preliminary secondary meter support. See Settings tab for selection.
|
||||
Some scales incomplete.
|
||||
|
||||
Added SWR and ALC scales to the meter.
|
||||
|
||||
Fix error in scale of power meter
|
||||
|
||||
- 20210716
|
||||
|
||||
Power meter for transmit. Much work remains on this meter alone.
|
||||
|
||||
Get antenna status on start-up and slow poll for it.
|
||||
|
||||
Add RX antenna selection for rigs that support it
|
||||
|
||||
- 20210714
|
||||
|
||||
Preferences added for Anti-Alias and Interpolate.
|
||||
|
||||
- 20210713
|
||||
|
||||
Added waterfall display options: anti-alias and interpolate. Not in
|
||||
preferences yet. Debug button enables wf pan and zoom.
|
||||
|
||||
- 20210711
|
||||
|
||||
Allow user to select whether to confirm exit or not
|
||||
|
||||
- 20210709
|
||||
|
||||
Reset PTT timer for control-R keystroke.
|
||||
|
||||
Added a fix to keep the local frequency in-sync with any recent commands
|
||||
sent to the radio.
|
||||
|
||||
Added more support for the IC-7600 in rigCaps.
|
||||
|
||||
Added time, date, and UTC offset commands. Currently initiated by the
|
||||
debug button. There seems to be a bug in the 7300 where the UTC offset
|
||||
has one hour subtracted, ie, -7 HRS becomes -8 HRS. The hex command
|
||||
appears to be sent correctly.
|
||||
|
||||
- 20210708
|
||||
|
||||
Delete oldest entry from UDP buffer before adding new one.
|
||||
|
||||
If pty connected s/w sends a disable transceive command, dont' send any transceive commands to it
|
||||
|
||||
New about box!
|
||||
|
||||
|
||||
- 20210706
|
||||
|
||||
Local af gain now has anti-log audio pot taper.
|
||||
|
||||
Only start audio when stream is ready
|
||||
|
||||
- 20210705
|
||||
|
||||
Added transceiver adjustment window show code, for the debug button only
|
||||
currently.
|
||||
|
||||
Added window title text change to show radio model. Needs to be checked
|
||||
cross-platform. On Linux Mint, displays: "IC-7300 -- wfview"
|
||||
|
||||
Applying setup.volume within audio handler if the audio handled is an
|
||||
output. Added this to the init function.
|
||||
|
||||
waterfall theme is now saved.
|
||||
|
||||
Added local af gain and wf length to the preferences.
|
||||
|
||||
- 20210702
|
||||
fixed small error where the tx latency was not copied in the UI
|
||||
|
||||
- 20210626
|
||||
Merge branch 'sequence' of gitlab.com:eliggett/wfview into sequence
|
||||
|
||||
Duplicate of existing command.
|
||||
|
||||
Remove unnecessary escape sequence
|
||||
|
||||
Fix for fix of missing __PRETTY_FUNCTION__
|
||||
|
||||
Add __PRETTY_FUNCTION__ for compilers that don't have it.
|
||||
|
||||
- 20210625
|
||||
Mode changes from the combo box now use the que. There are still other
|
||||
methods to change mode which will transition shortly.
|
||||
|
||||
Faster PTT
|
||||
|
||||
Added PTT to the queue.
|
||||
|
||||
Added unique priority insertion methods.
|
||||
|
||||
Changed how commands with parameter data are added.
|
||||
|
||||
Initial queued "set" command commit. Only the frequency set command is
|
||||
used so far, and only for the "Frequency" tab and the tuning knob.
|
||||
|
||||
- 20210624
|
||||
Quick hack for WFM forcing FIL1 always
|
||||
|
||||
- 20210621
|
||||
Added polling button
|
||||
|
||||
Moving to std::deque (double-ended que).
|
||||
|
||||
- 20210620
|
||||
|
||||
IC-R8600 span is now received into the UI correctly.
|
||||
|
||||
New unified outgoing command queue. Tested on IC-9700 and IC-718 (to
|
||||
remote wfview server). CPU usage seems higher but please check your
|
||||
system.
|
||||
|
||||
Timing seems to be acceptable but could probably use some tweaks.
|
||||
S-meter polling is 25ms for fast radios, and slower rates for slower
|
||||
radios. Half-duplex serial radios receive 3x slower polling to make room
|
||||
for replies.
|
||||
|
||||
For Freq, Mode, etc "regular" constant polling (new feature):
|
||||
|
||||
IC-9700 polling is 5 per second, IC-718 is 1-2 per second.
|
||||
|
||||
Just helps keep the UI in sync with changes taking place at the rig. The
|
||||
polling is slow enough that it doesn't impact anything. But quick enough
|
||||
that it catches discrepencies pretty quickly.
|
||||
|
||||
- 20210619
|
||||
|
||||
Added a few more slider things
|
||||
|
||||
whatsnew: improved IC-R8600
|
||||
|
||||
- 20210618
|
||||
|
||||
Additional support for the IC-R8600, including wider scope spans.
|
||||
|
||||
Minor change to remove some old debug code that snuck in.
|
||||
|
||||
If no rig caps, then don't mess with the window!
|
||||
|
||||
Added full duplex comms parameter to rigCaps. We assume half-duplex
|
||||
until we receive a reply to rigID.
|
||||
|
||||
Fixed accidental s-meter timing parameter change.
|
||||
|
||||
- 20210617
|
||||
|
||||
Radios without spectrum do not show spectrum, and, the window properly
|
||||
resizes for those controls. Also, a new key command, control-shift-d has
|
||||
been added to run debug functions from any tab in the program.
|
||||
|
||||
- 20210615
|
||||
|
||||
Additional code to hide/show spectrum and correcting an issue with the
|
||||
rig name not populating for non-spectrum radios.
|
||||
|
||||
Dynamic show/hide spectrum for rigs without this feature.
|
||||
|
||||
Additional data corruption checking.
|
||||
|
||||
- 20210614
|
||||
|
||||
Changed collision detection code so that we can more easily see what
|
||||
message was missed.
|
||||
|
||||
Added collision detection for serial commands. Collisions are aparently
|
||||
frequent for true 1-wire CI-V radios.
|
||||
|
||||
We now calculate polling rates immediately upon receiveCommReady for
|
||||
serial connections. For network connections, we assume sane values and
|
||||
modify once we receive the baud rate from the server.
|
||||
|
||||
Add Neon (ARM) support to resampler
|
||||
|
||||
Revert to using resampler directory rather than opus-tools submodule
|
||||
|
||||
- 20210612
|
||||
|
||||
Add tooltip showing percentage of TX power when slider is moved
|
||||
|
||||
- 20210611
|
||||
|
||||
adding a second path/way for the qcustomplot link if the first fails
|
||||
|
||||
Update udpserver.cpp
|
||||
|
||||
Use global watchdog rather than per-connection
|
||||
|
|
|
@ -75,7 +75,7 @@ we need to add packages to be able to build the stuff.
|
|||
- sudo zypper in --type pattern devel_basis
|
||||
- sudo zypper in libQt5Widgets-devel libqt5-qtbase-common-devel libqt5-qtserialport-devel libQt5SerialPort5 qcustomplot-devel libqcustomplot2 libQt5PrintSupport-devel libqt5-qtmultimedia-devel
|
||||
|
||||
now get and install qt5:
|
||||
optional (mainly for development specifics): get and install qt5:
|
||||
|
||||
- wget http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run
|
||||
- chmod +x qt-unified-linux-x64-online.run
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# How to install wfview without building yourself on selected linux versions
|
||||
# How to install wfview without building yourself on selected linux versions
|
||||
|
||||
|
||||
|
||||
|
@ -22,10 +22,12 @@ Debian 11 (Debian 10 is outdated)
|
|||
Fedora 33
|
||||
Fedora 34
|
||||
mint 20.1 (and up?)
|
||||
openSUSE 15.x
|
||||
openSUSE Tumbleweed
|
||||
openSUSE 15.2
|
||||
openSUSE 15.3 (see notes at the end)
|
||||
openSUSE Tumbleweed(s)
|
||||
SLES 15.x
|
||||
Ubuntu 20.04.2 and up (?)
|
||||
Ubuntu 20.04.2
|
||||
mint 20.2 (see notes at the end)
|
||||
~~~
|
||||
|
||||
|
||||
|
@ -69,12 +71,37 @@ note: if the above symlink fails, use the following line to fix the library link
|
|||
sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/libqcustomplot.so.2
|
||||
~~~
|
||||
|
||||
### openSUSE/Tumbleweed/SLES:
|
||||
### Mint 20.2
|
||||
~~~
|
||||
|
||||
SEE THE NOTES AT THE END. You need wfview153 binary here
|
||||
|
||||
sudo apt install libqcustomplot2.0 libqt5multimedia5 libqt5serialport5
|
||||
sudo ln -s /usr/lib64/libqcustomplot-qt5.so.2 /usr/lib64/libqcustomplot.so.2
|
||||
wfview
|
||||
|
||||
note: if the above symlink fails, use the following line to fix the library link:
|
||||
|
||||
sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/libqcustomplot.so.2
|
||||
~~~
|
||||
|
||||
|
||||
### openSUSE/Tumbleweed/SLES based on 15.2:
|
||||
~~~
|
||||
sudo zypper in libqcustomplot2 libQt5SerialPort5
|
||||
wfview
|
||||
~~~
|
||||
|
||||
### openSUSE/Tumbleweed/SLES based on 15.3:
|
||||
~~~
|
||||
|
||||
SEE THE NOTES AT THE END. You need wfview153 here
|
||||
|
||||
sudo zypper in libqcustomplot2 libQt5SerialPort5
|
||||
wfview
|
||||
~~~
|
||||
|
||||
|
||||
### UBUNTU:
|
||||
~~~
|
||||
sudo apt install libqcustomplot2.0 libqt5multimedia5 libqt5serialport5
|
||||
|
@ -89,4 +116,18 @@ sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/l
|
|||
|
||||
|
||||
|
||||
### notes:
|
||||
~~~
|
||||
|
||||
Some newer versions of mint. ubuntu, openSUSE have different kernels and such which cause wfview to segfault.
|
||||
|
||||
For these cases we created two binaries: one for current systems ("wfview") and one for the new systems ("wfview153")
|
||||
|
||||
So if you encounter a SEGFAULT at start:
|
||||
|
||||
go in to the dist directory, rename wfview to wfvie152; rename wfview153 to wfview and re-execute the install.sh
|
||||
script
|
||||
|
||||
~~~
|
||||
|
||||
|
||||
|
|
4
WHATSNEW
4
WHATSNEW
|
@ -1,7 +1,7 @@
|
|||
|
||||
The following highlights are in this dot-release:
|
||||
|
||||
added IC7700
|
||||
added IC7700, 718, 7100. (more testing needed)
|
||||
fixes and improvements to audio
|
||||
ability to choose between rtaudio and qtmultimedia (default) as compile time option
|
||||
fixes and lots of improvements at the usb-server end
|
||||
|
@ -12,3 +12,5 @@ The following highlights are in this dot-release:
|
|||
wf display disappears when there is no wf capable rig
|
||||
IC R8600 support improved
|
||||
for older rigs added a polling timing box to keep stuff keeping smooth
|
||||
Local af gain now has anti-log audio pot taper.
|
||||
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
#include "aboutbox.h"
|
||||
#include "ui_aboutbox.h"
|
||||
|
||||
aboutbox::aboutbox(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::aboutbox)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle("About wfview");
|
||||
setWindowIcon(QIcon(":resources/wfview.png"));
|
||||
|
||||
ui->logoBtn->setIcon(QIcon(":resources/wfview.png"));
|
||||
ui->logoBtn->setStyleSheet("Text-align:left");
|
||||
|
||||
ui->topText->setText("wfview version 1.1");
|
||||
|
||||
QString head = QString("<html><head></head><body>");
|
||||
QString copyright = QString("Copyright 2017-2021 Elliott H. Liggett, W6EL. All rights reserved. wfview source code is <a href=\"https://gitlab.com/eliggett/wfview/-/blob/master/LICENSE\">licensed</a> under the GNU GPLv3.");
|
||||
QString nacode = QString("<br/><br/>Networking, audio, rigctl server, and much more written by Phil Taylor, M0VSE");
|
||||
QString doctest = QString("<br/><br/>Testing, documentation, bug fixes, and development mentorship from<br/>Roeland Jansen, PA3MET, and Jim Nijkamp, PA8E.");
|
||||
|
||||
|
||||
QString ssCredit = QString("<br/><br/>Stylesheet <a href=\"https://github.com/ColinDuquesnoy/QDarkStyleSheet/tree/master/qdarkstyle\" style=\"color: cyan;\">qdarkstyle</a> used under MIT license, stored in /usr/share/wfview/stylesheets/.");
|
||||
|
||||
QString website = QString("<br/><br/>Please visit <a href=\"https://wfview.org/\" style=\"color: cyan;\">https://wfview.org/</a> for the latest information.");
|
||||
QString docs = QString("<br/><br/>Be sure to check the <a href=\"https://wfview.org/wfview-user-manual/\" style=\"color: cyan;\">User Manual</a> and <a href=\"https://forum.wfview.org/\" style=\"color: cyan;\">the Forum</a> if you have any questions.");
|
||||
QString support = QString("<br/><br/>For support, please visit <a href=\"https://forum.wfview.org/\">the official wfview support forum</a>.");
|
||||
QString gitcodelink = QString("<a href=\"https://gitlab.com/eliggett/wfview/-/tree/%1\" style=\"color: cyan;\">").arg(GITSHORT);
|
||||
|
||||
QString contact = QString("<br/>email W6EL: kilocharlie8@gmail.com");
|
||||
|
||||
QString buildInfo = QString("<br/><br/>Build " + gitcodelink + QString(GITSHORT) + "</a> on " + QString(__DATE__) + " at " + __TIME__ + " by " + UNAME + "@" + HOST);
|
||||
QString end = QString("</body></html>");
|
||||
|
||||
// Short credit strings:
|
||||
QString rsCredit = QString("<br/><br/><a href=\"https://www.speex.org/\" style=\"color: cyan;\">Speex</a> Resample library Copyright 2003-2008 Jean-Marc Valin");
|
||||
#if defined(RTAUDIO)
|
||||
QString rtaudiocredit = QString("<br/><br/>RT Audio, from <a href=\"https://www.music.mcgill.ca/~gary/rtaudio/index.html\">Gary P. Scavone</a>");
|
||||
#endif
|
||||
|
||||
#if defined(PORTAUDIO)
|
||||
QString portaudiocredit = QString("<br/><br/>Port Audio, from <a href=\"http://portaudio.com\">The Port Audio Community</a>");
|
||||
#endif
|
||||
|
||||
QString qcpcredit = QString("<br/><br/>The waterfall and spectrum plot graphics use QCustomPlot, from <a href=\"https://www.qcustomplot.com/\">Emanuel Eichhammer</a>");
|
||||
QString qtcredit = QString("<br/><br/>This copy of wfview was built against Qt version %1").arg(QT_VERSION_STR);
|
||||
|
||||
// Acknowledgement:
|
||||
QString wfviewcommunityack = QString("<br/><br/>The developers of wfview wish to thank the many contributions from the wfview community at-large, including ideas, bug reports, and fixes.");
|
||||
QString kappanhangack = QString("<br/><br/>Special thanks to Norbert Varga, and the <a href=\"https://github.com/nonoo/kappanhang\">nonoo/kappanhang team</a> for their initial work on the OEM protocol.");
|
||||
|
||||
QString sxcreditcopyright = QString("Speex copyright notice: \
|
||||
Copyright (C) 2003 Jean-Marc Valin\n\
|
||||
Redistribution and use in source and binary forms, with or without\n\
|
||||
modification, are permitted provided that the following conditions\n\
|
||||
are met:\n\
|
||||
- Redistributions of source code must retain the above copyright\n\
|
||||
notice, this list of conditions and the following disclaimer.\n\
|
||||
- Redistributions in binary form must reproduce the above copyright\n\
|
||||
notice, this list of conditions and the following disclaimer in the\n\
|
||||
documentation and/or other materials provided with the distribution.\n\
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its\n\
|
||||
contributors may be used to endorse or promote products derived from\n\
|
||||
this software without specific prior written permission.\n\
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR\n\
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n\
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n\
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n\
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n\
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n\
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n\
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.");
|
||||
|
||||
|
||||
// String it all together:
|
||||
|
||||
QString aboutText = head + copyright + "\n" + nacode + "\n" + doctest + wfviewcommunityack;
|
||||
aboutText.append(website + "\n"+ docs + support + contact +"\n");
|
||||
aboutText.append("\n" + ssCredit + "\n" + rsCredit + "\n");
|
||||
|
||||
#if defined(RTAUDIO)
|
||||
aboutText.append(rtaudiocredit);
|
||||
#endif
|
||||
|
||||
#if defined(PORTAUDIO)
|
||||
aboutText.append(portaudiocredit);
|
||||
#endif
|
||||
|
||||
aboutText.append(kappanhangack + qcpcredit + qtcredit);
|
||||
aboutText.append("<br/><br/>");
|
||||
aboutText.append("<pre>" + sxcreditcopyright + "</pre>");
|
||||
aboutText.append("<br/><br/>");
|
||||
|
||||
aboutText.append(end);
|
||||
ui->midTextBox->setText(aboutText);
|
||||
ui->bottomText->setText(buildInfo);
|
||||
ui->midTextBox->setFocus();
|
||||
}
|
||||
|
||||
aboutbox::~aboutbox()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void aboutbox::on_logoBtn_clicked()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl("https://www.wfview.org/"));
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef ABOUTBOX_H
|
||||
#define ABOUTBOX_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDesktopServices>
|
||||
|
||||
namespace Ui {
|
||||
class aboutbox;
|
||||
}
|
||||
|
||||
class aboutbox : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit aboutbox(QWidget *parent = 0);
|
||||
~aboutbox();
|
||||
|
||||
private slots:
|
||||
void on_logoBtn_clicked();
|
||||
|
||||
private:
|
||||
Ui::aboutbox *ui;
|
||||
};
|
||||
|
||||
#endif // ABOUTBOX_H
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>aboutbox</class>
|
||||
<widget class="QWidget" name="aboutbox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>700</width>
|
||||
<height>567</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="logoBtn">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>128</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="topText">
|
||||
<property name="text">
|
||||
<string>wfview version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="midTextBox">
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Detailed text here</p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="bottomText">
|
||||
<property name="text">
|
||||
<string>Build String</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -91,7 +91,10 @@ bool audioHandler::init(audioSetup setupIn)
|
|||
|
||||
tempBuf.sent = 0;
|
||||
|
||||
|
||||
if(!setup.isinput)
|
||||
{
|
||||
this->setVolume(setup.localAFgain);
|
||||
}
|
||||
|
||||
#if defined(RTAUDIO)
|
||||
#if !defined(Q_OS_MACX)
|
||||
|
@ -322,7 +325,9 @@ void audioHandler::start()
|
|||
|
||||
void audioHandler::setVolume(unsigned char volume)
|
||||
{
|
||||
this->volume = (qreal)volume/255.0;
|
||||
//this->volume = (qreal)volume/255.0;
|
||||
this->volume = audiopot[volume];
|
||||
|
||||
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "setVolume: " << volume << "(" << this->volume << ")";
|
||||
}
|
||||
|
||||
|
|
|
@ -33,11 +33,14 @@ typedef signed short MY_TYPE;
|
|||
#include <QMap>
|
||||
#include "resampler/speex_resampler.h"
|
||||
#include "ring/ring.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "opus.h"
|
||||
#else
|
||||
#include "opus/opus.h"
|
||||
#endif
|
||||
#include "audiotaper.h"
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
@ -71,6 +74,7 @@ struct audioSetup {
|
|||
QAudioDeviceInfo port;
|
||||
#endif
|
||||
quint8 resampleQuality;
|
||||
unsigned char localAFgain;
|
||||
};
|
||||
|
||||
// For QtMultimedia, use a native QIODevice
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
#ifndef AUDIOTAPER_H
|
||||
#define AUDIOTAPER_H
|
||||
#include <QtMath>
|
||||
|
||||
const qreal audiopot[256] =
|
||||
{
|
||||
0.00000,
|
||||
0.00101,
|
||||
0.00202,
|
||||
0.00305,
|
||||
0.00409,
|
||||
0.00513,
|
||||
0.00619,
|
||||
0.00725,
|
||||
0.00832,
|
||||
0.00941,
|
||||
0.01050,
|
||||
0.01160,
|
||||
0.01272,
|
||||
0.01384,
|
||||
0.01497,
|
||||
0.01612,
|
||||
0.01727,
|
||||
0.01843,
|
||||
0.01961,
|
||||
0.02080,
|
||||
0.02199,
|
||||
0.02320,
|
||||
0.02442,
|
||||
0.02565,
|
||||
0.02689,
|
||||
0.02814,
|
||||
0.02940,
|
||||
0.03068,
|
||||
0.03196,
|
||||
0.03326,
|
||||
0.03457,
|
||||
0.03589,
|
||||
0.03723,
|
||||
0.03857,
|
||||
0.03993,
|
||||
0.04130,
|
||||
0.04268,
|
||||
0.04408,
|
||||
0.04548,
|
||||
0.04690,
|
||||
0.04834,
|
||||
0.04978,
|
||||
0.05124,
|
||||
0.05272,
|
||||
0.05420,
|
||||
0.05570,
|
||||
0.05721,
|
||||
0.05874,
|
||||
0.06028,
|
||||
0.06184,
|
||||
0.06341,
|
||||
0.06499,
|
||||
0.06659,
|
||||
0.06820,
|
||||
0.06982,
|
||||
0.07146,
|
||||
0.07312,
|
||||
0.07479,
|
||||
0.07648,
|
||||
0.07818,
|
||||
0.07990,
|
||||
0.08163,
|
||||
0.08338,
|
||||
0.08514,
|
||||
0.08692,
|
||||
0.08872,
|
||||
0.09053,
|
||||
0.09236,
|
||||
0.09421,
|
||||
0.09607,
|
||||
0.09795,
|
||||
0.09984,
|
||||
0.10176,
|
||||
0.10369,
|
||||
0.10564,
|
||||
0.10760,
|
||||
0.10959,
|
||||
0.11159,
|
||||
0.11361,
|
||||
0.11565,
|
||||
0.11770,
|
||||
0.11978,
|
||||
0.12187,
|
||||
0.12399,
|
||||
0.12612,
|
||||
0.12827,
|
||||
0.13044,
|
||||
0.13263,
|
||||
0.13484,
|
||||
0.13707,
|
||||
0.13933,
|
||||
0.14160,
|
||||
0.14389,
|
||||
0.14620,
|
||||
0.14854,
|
||||
0.15089,
|
||||
0.15327,
|
||||
0.15567,
|
||||
0.15809,
|
||||
0.16053,
|
||||
0.16299,
|
||||
0.16548,
|
||||
0.16799,
|
||||
0.17052,
|
||||
0.17307,
|
||||
0.17565,
|
||||
0.17825,
|
||||
0.18088,
|
||||
0.18353,
|
||||
0.18620,
|
||||
0.18889,
|
||||
0.19162,
|
||||
0.19436,
|
||||
0.19713,
|
||||
0.19993,
|
||||
0.20275,
|
||||
0.20560,
|
||||
0.20847,
|
||||
0.21137,
|
||||
0.21429,
|
||||
0.21725,
|
||||
0.22022,
|
||||
0.22323,
|
||||
0.22626,
|
||||
0.22932,
|
||||
0.23241,
|
||||
0.23553,
|
||||
0.23867,
|
||||
0.24184,
|
||||
0.24504,
|
||||
0.24828,
|
||||
0.25153,
|
||||
0.25482,
|
||||
0.25814,
|
||||
0.26149,
|
||||
0.26487,
|
||||
0.26828,
|
||||
0.27172,
|
||||
0.27520,
|
||||
0.27870,
|
||||
0.28224,
|
||||
0.28580,
|
||||
0.28941,
|
||||
0.29304,
|
||||
0.29670,
|
||||
0.30040,
|
||||
0.30414,
|
||||
0.30790,
|
||||
0.31170,
|
||||
0.31554,
|
||||
0.31941,
|
||||
0.32331,
|
||||
0.32725,
|
||||
0.33123,
|
||||
0.33524,
|
||||
0.33929,
|
||||
0.34338,
|
||||
0.34750,
|
||||
0.35166,
|
||||
0.35586,
|
||||
0.36009,
|
||||
0.36437,
|
||||
0.36868,
|
||||
0.37303,
|
||||
0.37742,
|
||||
0.38185,
|
||||
0.38633,
|
||||
0.39084,
|
||||
0.39539,
|
||||
0.39999,
|
||||
0.40462,
|
||||
0.40930,
|
||||
0.41402,
|
||||
0.41878,
|
||||
0.42359,
|
||||
0.42844,
|
||||
0.43333,
|
||||
0.43827,
|
||||
0.44326,
|
||||
0.44828,
|
||||
0.45336,
|
||||
0.45848,
|
||||
0.46364,
|
||||
0.46886,
|
||||
0.47412,
|
||||
0.47943,
|
||||
0.48478,
|
||||
0.49019,
|
||||
0.49564,
|
||||
0.50115,
|
||||
0.50670,
|
||||
0.51230,
|
||||
0.51796,
|
||||
0.52366,
|
||||
0.52942,
|
||||
0.53523,
|
||||
0.54110,
|
||||
0.54701,
|
||||
0.55298,
|
||||
0.55900,
|
||||
0.56508,
|
||||
0.57122,
|
||||
0.57741,
|
||||
0.58365,
|
||||
0.58995,
|
||||
0.59631,
|
||||
0.60273,
|
||||
0.60920,
|
||||
0.61574,
|
||||
0.62233,
|
||||
0.62898,
|
||||
0.63570,
|
||||
0.64247,
|
||||
0.64931,
|
||||
0.65620,
|
||||
0.66316,
|
||||
0.67019,
|
||||
0.67727,
|
||||
0.68442,
|
||||
0.69164,
|
||||
0.69892,
|
||||
0.70627,
|
||||
0.71368,
|
||||
0.72116,
|
||||
0.72871,
|
||||
0.73633,
|
||||
0.74402,
|
||||
0.75178,
|
||||
0.75960,
|
||||
0.76750,
|
||||
0.77547,
|
||||
0.78351,
|
||||
0.79163,
|
||||
0.79981,
|
||||
0.80808,
|
||||
0.81641,
|
||||
0.82483,
|
||||
0.83332,
|
||||
0.84188,
|
||||
0.85053,
|
||||
0.85925,
|
||||
0.86805,
|
||||
0.87693,
|
||||
0.88590,
|
||||
0.89494,
|
||||
0.90407,
|
||||
0.91327,
|
||||
0.92257,
|
||||
0.93194,
|
||||
0.94140,
|
||||
0.95095,
|
||||
0.96058,
|
||||
0.97030,
|
||||
0.98011,
|
||||
0.99001,
|
||||
1.00000
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // AUDIOTAPER_H
|
|
@ -12,6 +12,7 @@ Q_DECLARE_LOGGING_CATEGORY(logUdp)
|
|||
Q_DECLARE_LOGGING_CATEGORY(logUdpServer)
|
||||
Q_DECLARE_LOGGING_CATEGORY(logRigCtlD)
|
||||
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(__PRETTY_FUNCTION__)
|
||||
#define __PRETTY_FUNCTION__ __FUNCSIG__
|
||||
#endif
|
||||
|
|
398
meter.cpp
398
meter.cpp
|
@ -23,6 +23,8 @@ meter::meter(QWidget *parent) : QWidget(parent)
|
|||
//
|
||||
// Text in qdarkstylesheet seems to be #EFF0F1
|
||||
|
||||
meterType = meterS;
|
||||
|
||||
currentColor.setNamedColor("#148CD2");
|
||||
currentColor = currentColor.darker();
|
||||
|
||||
|
@ -34,8 +36,47 @@ meter::meter(QWidget *parent) : QWidget(parent)
|
|||
lowTextColor.setNamedColor("#eff0f1");
|
||||
lowLineColor = lowTextColor;
|
||||
|
||||
avgLevels.resize(averageBalisticLength, 0);
|
||||
peakLevels.resize(peakBalisticLength, 0);
|
||||
|
||||
}
|
||||
|
||||
void meter::setMeterType(meterKind type)
|
||||
{
|
||||
if(type == meterType)
|
||||
return;
|
||||
|
||||
meterType = type;
|
||||
// clear average and peak vectors:
|
||||
current = 0;
|
||||
average = 0;
|
||||
peak = 0;
|
||||
|
||||
avgLevels.clear();
|
||||
peakLevels.clear();
|
||||
avgLevels.resize(averageBalisticLength, 0);
|
||||
peakLevels.resize(peakBalisticLength, 0);
|
||||
|
||||
peakPosition = 0;
|
||||
avgPosition = 0;
|
||||
// re-draw scale:
|
||||
update();
|
||||
}
|
||||
|
||||
meterKind meter::getMeterType()
|
||||
{
|
||||
return meterType;
|
||||
}
|
||||
|
||||
void meter::setMeterShortString(QString s)
|
||||
{
|
||||
meterShortString = s;
|
||||
}
|
||||
|
||||
QString meter::getMeterShortString()
|
||||
{
|
||||
return meterShortString;
|
||||
}
|
||||
|
||||
void meter::paintEvent(QPaintEvent *)
|
||||
{
|
||||
|
@ -45,31 +86,125 @@ void meter::paintEvent(QPaintEvent *)
|
|||
// The end effect, is that the drawing functions will all
|
||||
// scale to the window size.
|
||||
|
||||
painter.setWindow(QRect(0, 0, 255+mstart, 50));
|
||||
drawScale(&painter);
|
||||
painter.setWindow(QRect(0, 0, 255+mXstart, widgetWindowHeight));
|
||||
|
||||
// Current:
|
||||
painter.setPen(currentColor);
|
||||
painter.setBrush(currentColor);
|
||||
painter.drawRect(mstart,mheight,current,mstart);
|
||||
|
||||
// Average:
|
||||
painter.setPen(averageColor);
|
||||
painter.setBrush(averageColor);
|
||||
painter.drawRect(mstart+average-1,mheight,1,mstart);
|
||||
|
||||
// Peak:
|
||||
painter.setPen(peakColor);
|
||||
painter.setBrush(peakColor);
|
||||
if(peak > 120)
|
||||
if(this->height() > widgetWindowHeight )
|
||||
{
|
||||
// 120 = +S9
|
||||
painter.setBrush(Qt::red);
|
||||
painter.setPen(Qt::red);
|
||||
// Clamp down on stretching fonts.
|
||||
// TODO: Make this more elegant
|
||||
painter.setFont(QFont(this->fontInfo().family(), widgetWindowHeight/3.5));
|
||||
widgetWindowHeight = this->height();
|
||||
painter.setWindow(QRect(0, 0, 255+mXstart, widgetWindowHeight));
|
||||
barHeight = widgetWindowHeight / 2;
|
||||
|
||||
|
||||
//painter.setFont(QFont(this->fontInfo().family(), widgetWindowHeight/2.5));
|
||||
}
|
||||
|
||||
painter.drawRect(mstart+peak-1,mheight,2,mstart);
|
||||
switch(meterType)
|
||||
{
|
||||
case meterS:
|
||||
peakRedLevel = 120; // S9+
|
||||
drawScaleS(&painter);
|
||||
break;
|
||||
case meterPower:
|
||||
peakRedLevel = 210; // 100%
|
||||
drawScalePo(&painter);
|
||||
break;
|
||||
case meterALC:
|
||||
peakRedLevel = 100;
|
||||
drawScaleALC(&painter);
|
||||
break;
|
||||
case meterSWR:
|
||||
peakRedLevel = 100; // SWR 2.5
|
||||
drawScaleSWR(&painter);
|
||||
break;
|
||||
case meterCenter:
|
||||
peakRedLevel = 256; // No need for red here
|
||||
drawScaleCenter(&painter);
|
||||
break;
|
||||
case meterVoltage:
|
||||
peakRedLevel = 241;
|
||||
drawScaleVd(&painter);
|
||||
break;
|
||||
default:
|
||||
peakRedLevel = 200;
|
||||
drawScaleRaw(&painter);
|
||||
break;
|
||||
}
|
||||
|
||||
// Current: the most-current value.
|
||||
// Draws a bar from start to value.
|
||||
painter.setPen(currentColor);
|
||||
painter.setBrush(currentColor);
|
||||
|
||||
if(meterType == meterCenter)
|
||||
{
|
||||
painter.drawRect(mXstart+128,mYstart,current-128,barHeight);
|
||||
|
||||
// Average:
|
||||
painter.setPen(averageColor);
|
||||
painter.setBrush(averageColor);
|
||||
painter.drawRect(mXstart+average-1,mYstart,1,barHeight); // bar is 1 pixel wide, height = meter start?
|
||||
|
||||
// Peak:
|
||||
painter.setPen(peakColor);
|
||||
painter.setBrush(peakColor);
|
||||
if((peak > 191) || (peak < 63))
|
||||
{
|
||||
painter.setBrush(Qt::red);
|
||||
painter.setPen(Qt::red);
|
||||
}
|
||||
|
||||
painter.drawRect(mXstart+peak-1,mYstart,1,barHeight);
|
||||
|
||||
} else {
|
||||
|
||||
// X, Y, Width, Height
|
||||
painter.drawRect(mXstart,mYstart,current,barHeight);
|
||||
|
||||
// Average:
|
||||
painter.setPen(averageColor);
|
||||
painter.setBrush(averageColor);
|
||||
painter.drawRect(mXstart+average-1,mYstart,1,barHeight); // bar is 1 pixel wide, height = meter start?
|
||||
|
||||
// Peak:
|
||||
painter.setPen(peakColor);
|
||||
painter.setBrush(peakColor);
|
||||
if(peak > peakRedLevel)
|
||||
{
|
||||
painter.setBrush(Qt::red);
|
||||
painter.setPen(Qt::red);
|
||||
}
|
||||
|
||||
painter.drawRect(mXstart+peak-1,mYstart,2,barHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void meter::setLevel(int current)
|
||||
{
|
||||
this->current = current;
|
||||
|
||||
avgLevels[(avgPosition++)%averageBalisticLength] = current;
|
||||
peakLevels[(peakPosition++)%peakBalisticLength] = current;
|
||||
|
||||
int sum=0;
|
||||
|
||||
for(unsigned int i=0; i < (unsigned int)std::min(avgPosition, (int)avgLevels.size()); i++)
|
||||
{
|
||||
sum += avgLevels.at(i);
|
||||
}
|
||||
this->average = sum / std::min(avgPosition, (int)avgLevels.size());
|
||||
|
||||
this->peak = 0;
|
||||
|
||||
for(unsigned int i=0; i < peakLevels.size(); i++)
|
||||
{
|
||||
if( peakLevels.at(i) > this->peak)
|
||||
this->peak = peakLevels.at(i);
|
||||
}
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
void meter::setLevels(int current, int peak, int average)
|
||||
|
@ -77,6 +212,7 @@ void meter::setLevels(int current, int peak, int average)
|
|||
this->current = current;
|
||||
this->peak = peak;
|
||||
this->average = average;
|
||||
|
||||
this->update();
|
||||
}
|
||||
|
||||
|
@ -86,17 +222,221 @@ void meter::updateDrawing(int num)
|
|||
length = num;
|
||||
}
|
||||
|
||||
// The drawScale functions draw the numbers and number unerline for each type of meter
|
||||
|
||||
void meter::drawScale(QPainter *qp)
|
||||
void meter::drawScaleRaw(QPainter *qp)
|
||||
{
|
||||
qp->setPen(lowTextColor);
|
||||
qp->setFont(QFont("Arial", fontSize));
|
||||
int i=mstart;
|
||||
//qp->setFont(QFont("Arial", fontSize));
|
||||
int i=mXstart;
|
||||
for(; i<mXstart+256; i+=20)
|
||||
{
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg(i) );
|
||||
}
|
||||
|
||||
// Now the lines:
|
||||
qp->setPen(lowLineColor);
|
||||
|
||||
// Line: X1, Y1 -->to--> X2, Y2
|
||||
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
|
||||
qp->setPen(Qt::red);
|
||||
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
|
||||
|
||||
}
|
||||
|
||||
void meter::drawScaleVd(QPainter *qp)
|
||||
{
|
||||
qp->setPen(lowTextColor);
|
||||
//qp->setFont(QFont("Arial", fontSize));
|
||||
|
||||
// 7300/9700 and others:
|
||||
int midPointDn = 13;
|
||||
int midPointVd = 10;
|
||||
|
||||
// 705:
|
||||
//int midPointDn = 75;
|
||||
//int midPointVd = 5;
|
||||
|
||||
int highPointDn = 241;
|
||||
int highPointVd = 16;
|
||||
float VdperDn = (float)(highPointVd-midPointVd) / float(highPointDn-midPointDn);
|
||||
|
||||
int i=mXstart;
|
||||
for(; i<mXstart+midPointDn; i+=midPointDn/2)
|
||||
{
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg( (int)((i-mXstart) * (float(midPointVd) / float(midPointDn)) )) );
|
||||
}
|
||||
|
||||
for(; i<mXstart+255; i+= (highPointDn-midPointDn) / (highPointVd-midPointVd))
|
||||
{
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg( (int) std::round( ((i-mXstart-midPointDn) * (VdperDn) ) + (midPointVd) )));
|
||||
qp->drawLine(i,scaleTextYstart, i, scaleTextYstart+5);
|
||||
}
|
||||
|
||||
// Now the lines:
|
||||
qp->setPen(lowLineColor);
|
||||
|
||||
// Line: X1, Y1 -->to--> X2, Y2
|
||||
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
|
||||
qp->setPen(Qt::red);
|
||||
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
|
||||
|
||||
}
|
||||
|
||||
void meter::drawScaleCenter(QPainter *qp)
|
||||
{
|
||||
// No known units
|
||||
qp->setPen(lowLineColor);
|
||||
qp->drawText(60+mXstart,scaleTextYstart, QString("-"));
|
||||
|
||||
qp->setPen(Qt::green);
|
||||
// Attempt to draw the zero at the actual center
|
||||
qp->drawText(128-2+mXstart,scaleTextYstart, QString("0"));
|
||||
|
||||
qp->setPen(lowLineColor);
|
||||
qp->drawText(195+mXstart,scaleTextYstart, QString("+"));
|
||||
|
||||
|
||||
qp->setPen(lowLineColor);
|
||||
qp->drawLine(mXstart,scaleLineYstart,128-32+mXstart,scaleLineYstart);
|
||||
|
||||
qp->setPen(Qt::green);
|
||||
qp->drawLine(128-32+mXstart,scaleLineYstart,128+32+mXstart,scaleLineYstart);
|
||||
|
||||
qp->setPen(lowLineColor);
|
||||
qp->drawLine(128+32+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
|
||||
}
|
||||
|
||||
|
||||
void meter::drawScalePo(QPainter *qp)
|
||||
{
|
||||
//From the manual: "0000=0% to 0143=50% to 0213=100%"
|
||||
float dnPerWatt = 143.0 / 50.0;
|
||||
|
||||
qp->setPen(lowTextColor);
|
||||
//qp->setFont(QFont("Arial", fontSize));
|
||||
|
||||
int i=mXstart;
|
||||
// 13.3 DN per s-unit:
|
||||
int p=0;
|
||||
for(; i<mXstart+143; i+=(int)(10*dnPerWatt))
|
||||
{
|
||||
// Stop just before the next 10w spot
|
||||
if(i<mXstart+140)
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg(10*(p++)) );
|
||||
}
|
||||
|
||||
// Modify current scale position:
|
||||
|
||||
// Here, P is now 60 watts:
|
||||
// Higher scale:
|
||||
i = i - (int)(10*dnPerWatt); // back one tick first. Otherwise i starts at 178.
|
||||
//qDebug() << "meter i: " << i;
|
||||
dnPerWatt = (213-143.0) / 50.0; // 1.4 dn per watt
|
||||
// P=5 here.
|
||||
qp->setPen(Qt::yellow);
|
||||
int k=0;
|
||||
for(i=mXstart+143; i<mXstart+213; i+=(5*dnPerWatt))
|
||||
{
|
||||
k = 50+(( i-mXstart-143 ) / dnPerWatt);
|
||||
if(k==40||k==50||k==65||k==80)
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg(k) );
|
||||
}
|
||||
|
||||
// Now we're out past 100:
|
||||
qp->setPen(Qt::red);
|
||||
|
||||
for(i=mXstart+213; i<mXstart+255; i+=(10*dnPerWatt))
|
||||
{
|
||||
k = 50+(( i-mXstart-143 ) / dnPerWatt);
|
||||
if(k==100)
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg(k) );
|
||||
}
|
||||
|
||||
// Now the lines:
|
||||
qp->setPen(lowLineColor);
|
||||
|
||||
// Line: X1, Y1 -->to--> X2, Y2
|
||||
qp->drawLine(mXstart,scaleLineYstart,213+mXstart,scaleLineYstart);
|
||||
qp->setPen(Qt::red);
|
||||
qp->drawLine(213+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
|
||||
|
||||
(void)qp;
|
||||
}
|
||||
|
||||
void meter::drawScaleRxdB(QPainter *qp)
|
||||
{
|
||||
(void)qp;
|
||||
}
|
||||
|
||||
void meter::drawScaleALC(QPainter *qp)
|
||||
{
|
||||
// From the manual: 0000=Minimum to 0120=Maximum
|
||||
|
||||
qp->setPen(lowTextColor);
|
||||
//qp->setFont(QFont("Arial", fontSize));
|
||||
int i=mXstart;
|
||||
int alc=0;
|
||||
for(; i<mXstart+100; i += (20))
|
||||
{
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg(alc) );
|
||||
alc +=20;
|
||||
}
|
||||
|
||||
qp->setPen(Qt::red);
|
||||
|
||||
for(; i<mXstart+120; i+=(int)(10*i))
|
||||
{
|
||||
qp->drawText(i,scaleTextYstart, QString("+%1").arg(alc) );
|
||||
alc +=10;
|
||||
}
|
||||
|
||||
qp->setPen(lowLineColor);
|
||||
qp->drawLine(mXstart,scaleLineYstart,100+mXstart,scaleLineYstart);
|
||||
qp->setPen(Qt::red);
|
||||
qp->drawLine(100+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
|
||||
|
||||
(void)qp;
|
||||
}
|
||||
|
||||
void meter::drawScaleSWR(QPainter *qp)
|
||||
{
|
||||
// From the manual:
|
||||
// 0000=SWR1.0,
|
||||
// 0048=SWR1.5,
|
||||
// 0080=SWR2.0,
|
||||
// 0120=SWR3.0
|
||||
|
||||
qp->drawText(mXstart,scaleTextYstart, QString("1.0"));
|
||||
qp->drawText(24+mXstart,scaleTextYstart, QString("1.3"));
|
||||
qp->drawText(48+mXstart,scaleTextYstart, QString("1.5"));
|
||||
qp->drawText(80+mXstart,scaleTextYstart, QString("2.0"));
|
||||
qp->drawText(100+mXstart,scaleTextYstart, QString("2.5"));
|
||||
qp->drawText(120+mXstart,scaleTextYstart, QString("3.0"));
|
||||
|
||||
qp->setPen(lowLineColor);
|
||||
qp->drawLine(mXstart,scaleLineYstart,100+mXstart,scaleLineYstart);
|
||||
qp->setPen(Qt::red);
|
||||
qp->drawLine(100+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
|
||||
|
||||
(void)qp;
|
||||
}
|
||||
|
||||
void meter::drawScaleId(QPainter *qp)
|
||||
{
|
||||
(void)qp;
|
||||
}
|
||||
|
||||
void meter::drawScaleS(QPainter *qp)
|
||||
{
|
||||
qp->setPen(lowTextColor);
|
||||
//qp->setFont(QFont("Arial", fontSize));
|
||||
int i=mXstart;
|
||||
// 13.3 DN per s-unit:
|
||||
int s=0;
|
||||
for(; i<mstart+120; i+=13)
|
||||
for(; i<mXstart+120; i+=13)
|
||||
{
|
||||
qp->drawText(i,mstart, QString("%1").arg(s++) );
|
||||
qp->drawText(i,scaleTextYstart, QString("%1").arg(s++) );
|
||||
}
|
||||
|
||||
// 2 DN per 1 dB now:
|
||||
|
@ -109,16 +449,16 @@ void meter::drawScale(QPainter *qp)
|
|||
|
||||
qp->setPen(Qt::red);
|
||||
|
||||
for(; i<mstart+255; i+=40)
|
||||
for(; i<mXstart+255; i+=40)
|
||||
{
|
||||
qp->drawText(i,mstart, QString("+%1").arg(s) );
|
||||
qp->drawText(i,scaleTextYstart, QString("+%1").arg(s) );
|
||||
s = s + 20;
|
||||
}
|
||||
|
||||
qp->setPen(lowLineColor);
|
||||
|
||||
qp->drawLine(mstart,12,130,12);
|
||||
qp->drawLine(mXstart,scaleLineYstart,130,scaleLineYstart);
|
||||
qp->setPen(Qt::red);
|
||||
qp->drawLine(130,12,255,12);
|
||||
qp->drawLine(130,scaleLineYstart,255,scaleLineYstart);
|
||||
|
||||
}
|
||||
|
|
45
meter.h
45
meter.h
|
@ -3,6 +3,12 @@
|
|||
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <cmath>
|
||||
|
||||
#include "rigcommander.h" // for meter types
|
||||
|
||||
class meter : public QWidget
|
||||
{
|
||||
|
@ -17,20 +23,51 @@ public slots:
|
|||
|
||||
void updateDrawing(int num);
|
||||
void setLevels(int current, int peak, int average);
|
||||
void setLevel(int current);
|
||||
void setMeterType(meterKind type);
|
||||
void setMeterShortString(QString);
|
||||
QString getMeterShortString();
|
||||
meterKind getMeterType();
|
||||
|
||||
|
||||
private:
|
||||
//QPainter painter;
|
||||
int fontSize = 5;
|
||||
meterKind meterType;
|
||||
QString meterShortString;
|
||||
int fontSize = 10;
|
||||
int length=30;
|
||||
int current=0;
|
||||
int peak = 0;
|
||||
int average = 0;
|
||||
|
||||
int mstart = 10; // Starting point for S=0.
|
||||
int mheight = 14; // "thickness" of the meter block rectangle
|
||||
int averageBalisticLength = 30;
|
||||
int peakBalisticLength = 30;
|
||||
int avgPosition=0;
|
||||
int peakPosition=0;
|
||||
std::vector<unsigned char> avgLevels;
|
||||
std::vector<unsigned char> peakLevels;
|
||||
|
||||
void drawScale(QPainter *qp);
|
||||
|
||||
|
||||
int peakRedLevel=0;
|
||||
|
||||
int mXstart = 0; // Starting point for S=0.
|
||||
int mYstart = 14; // height, down from top, where the drawing starts
|
||||
int barHeight = 10; // Height of meter "bar" indicators
|
||||
int scaleLineYstart = 12;
|
||||
int scaleTextYstart = 10;
|
||||
|
||||
int widgetWindowHeight = mYstart + barHeight + 0; // height of drawing canvis.
|
||||
|
||||
void drawScaleS(QPainter *qp);
|
||||
void drawScaleCenter(QPainter *qp);
|
||||
void drawScalePo(QPainter *qp);
|
||||
void drawScaleRxdB(QPainter *qp);
|
||||
void drawScaleALC(QPainter *qp);
|
||||
void drawScaleSWR(QPainter *qp);
|
||||
void drawScaleVd(QPainter *qp);
|
||||
void drawScaleId(QPainter *qp);
|
||||
void drawScaleRaw(QPainter *qp);
|
||||
|
||||
QColor currentColor;
|
||||
QColor averageColor;
|
||||
|
|
|
@ -117,7 +117,7 @@ void pttyHandler::receiveDataFromRigToPtty(const QByteArray& data)
|
|||
{
|
||||
|
||||
int fePos=data.lastIndexOf((char)0xfe);
|
||||
if (fePos>0)
|
||||
if (fePos > 0 && data.length() > fePos+2)
|
||||
fePos=fePos-1;
|
||||
else
|
||||
{
|
||||
|
@ -125,7 +125,14 @@ void pttyHandler::receiveDataFromRigToPtty(const QByteArray& data)
|
|||
printHex(data,false,true);
|
||||
}
|
||||
|
||||
if (isConnected && (unsigned char)data[fePos+2] != 0xE1 && (unsigned char)data[fePos+3] != 0xE1)
|
||||
if (disableTransceive && ((unsigned char)data[fePos + 2] == 0x00 || (unsigned char)data[fePos + 3] == 0x00))
|
||||
{
|
||||
// Ignore data that is sent to/from transceive address as client has requested transceive disabled.
|
||||
qDebug(logSerial()) << "Transceive command filtered";
|
||||
return;
|
||||
}
|
||||
|
||||
if (isConnected && (unsigned char)data[fePos + 2] != 0xE1 && (unsigned char)data[fePos + 3] != 0xE1)
|
||||
{
|
||||
// send to the pseudo port as well
|
||||
// index 2 is dest, 0xE1 is wfview, 0xE0 is assumed to be the other device.
|
||||
|
@ -133,7 +140,7 @@ void pttyHandler::receiveDataFromRigToPtty(const QByteArray& data)
|
|||
// 0xE1 = wfview
|
||||
// 0xE0 = pseudo-term host
|
||||
// 0x00 = broadcast to all
|
||||
//qInfo(logSerial()) << "Sending data from radio to pseudo-terminal";
|
||||
//qInfo(logSerial()) << "Sending data from radio to pseudo-terminal";
|
||||
sendDataOut(data);
|
||||
}
|
||||
}
|
||||
|
@ -221,12 +228,16 @@ void pttyHandler::receiveDataIn(int fd) {
|
|||
reply[3] = inPortData[2];
|
||||
sendDataOut(inPortData); // Echo command back
|
||||
sendDataOut(reply);
|
||||
if (!disableTransceive) {
|
||||
qInfo(logSerial()) << "pty requested CI-V Transceive disable";
|
||||
disableTransceive = true;
|
||||
}
|
||||
}
|
||||
else if (inPortData.length() > lastFE + 2 && ((quint8)inPortData[lastFE + 1] == civId || (quint8)inPortData[lastFE + 2] == civId))
|
||||
{
|
||||
emit haveDataFromPort(inPortData);
|
||||
//qInfo(logSerial()) << "Data from pseudo term:";
|
||||
//printHex(inPortData, false, true);
|
||||
qDebug(logSerial()) << "Data from pseudo term:";
|
||||
printHex(inPortData, false, true);
|
||||
}
|
||||
|
||||
if (rolledBack)
|
||||
|
|
|
@ -65,7 +65,7 @@ private:
|
|||
bool isConnected=false; // port opened
|
||||
mutable QMutex mutex;
|
||||
void printHex(const QByteArray& pdata, bool printVert, bool printHoriz);
|
||||
|
||||
bool disableTransceive = false;
|
||||
QSocketNotifier *ptReader = nullptr;
|
||||
quint8 civId=0;
|
||||
};
|
||||
|
|
188
rigcommander.cpp
188
rigcommander.cpp
|
@ -133,7 +133,8 @@ void rigCommander::commSetup(unsigned char rigCivAddr, udpPreferences prefs, aud
|
|||
|
||||
connect(ptty, SIGNAL(haveSerialPortError(QString, QString)), this, SLOT(handleSerialPortError(QString, QString)));
|
||||
connect(this, SIGNAL(getMoreDebug()), ptty, SLOT(debugThis()));
|
||||
emit haveAfGain(255);
|
||||
|
||||
emit haveAfGain(rxSetup.localAFgain);
|
||||
}
|
||||
|
||||
// data from the comm port to the program:
|
||||
|
@ -1221,6 +1222,9 @@ void rigCommander::parseCommand()
|
|||
case '\x11':
|
||||
emit haveAttenuator((unsigned char)payloadIn.at(1));
|
||||
break;
|
||||
case '\x12':
|
||||
emit haveAntenna((unsigned char)payloadIn.at(1), (bool)payloadIn.at(2));
|
||||
break;
|
||||
case '\x14':
|
||||
// read levels
|
||||
parseLevels();
|
||||
|
@ -1385,6 +1389,11 @@ void rigCommander::parseLevels()
|
|||
emit haveMeter(meterS, level);
|
||||
rigState.sMeter = level;
|
||||
break;
|
||||
case '\x04':
|
||||
// Center (IC-R8600)
|
||||
emit haveMeter(meterCenter, level);
|
||||
rigState.sMeter = level;
|
||||
break;
|
||||
case '\x11':
|
||||
// RF-Power meter
|
||||
emit haveMeter(meterPower, level);
|
||||
|
@ -1913,6 +1922,9 @@ void rigCommander::getMeters(meterKind meter)
|
|||
case meterS:
|
||||
getSMeter();
|
||||
break;
|
||||
case meterCenter:
|
||||
getCenterMeter();
|
||||
break;
|
||||
case meterSWR:
|
||||
getSWRMeter();
|
||||
break;
|
||||
|
@ -1942,6 +1954,12 @@ void rigCommander::getSMeter()
|
|||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::getCenterMeter()
|
||||
{
|
||||
QByteArray payload("\x15\x04");
|
||||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::getRFPowerMeter()
|
||||
{
|
||||
QByteArray payload("\x15\x11");
|
||||
|
@ -2019,6 +2037,143 @@ void rigCommander::setRefAdjustFine(unsigned char level)
|
|||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::setTime(timekind t)
|
||||
{
|
||||
QByteArray payload;
|
||||
|
||||
switch(rigCaps.model)
|
||||
{
|
||||
case model705:
|
||||
payload.setRawData("\x1A\x05\x01\x66", 4);
|
||||
break;
|
||||
case model7300:
|
||||
payload.setRawData("\x1A\x05\x00\x95", 4);
|
||||
break;
|
||||
case model7610:
|
||||
payload.setRawData("\x1A\x05\x01\x59", 4);
|
||||
break;
|
||||
case model7700:
|
||||
payload.setRawData("\x1A\x05\x00\x59", 4);
|
||||
break;
|
||||
case model7850:
|
||||
payload.setRawData("\x1A\x05\x00\x96", 4);
|
||||
break;
|
||||
case model9700:
|
||||
payload.setRawData("\x1A\x05\x01\x80", 4);
|
||||
break;
|
||||
case modelR8600:
|
||||
payload.setRawData("\x1A\x05\x01\x32", 4);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
|
||||
}
|
||||
payload.append(convertNumberToHex(t.hours));
|
||||
payload.append(convertNumberToHex(t.minutes));
|
||||
//qDebug(logRig()) << "Setting time to this: ";
|
||||
//printHex(payload);
|
||||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::setDate(datekind d)
|
||||
{
|
||||
QByteArray payload;
|
||||
|
||||
switch(rigCaps.model)
|
||||
{
|
||||
case model705:
|
||||
payload.setRawData("\x1A\x05\x01\x65", 4);
|
||||
break;
|
||||
case model7300:
|
||||
payload.setRawData("\x1A\x05\x00\x94", 4);
|
||||
break;
|
||||
case model7610:
|
||||
payload.setRawData("\x1A\x05\x01\x58", 4);
|
||||
break;
|
||||
case model7700:
|
||||
payload.setRawData("\x1A\x05\x00\x58", 4);
|
||||
break;
|
||||
case model7850:
|
||||
payload.setRawData("\x1A\x05\x00\x95", 4);
|
||||
break;
|
||||
case model9700:
|
||||
payload.setRawData("\x1A\x05\x01\x79", 4);
|
||||
break;
|
||||
case modelR8600:
|
||||
payload.setRawData("\x1A\x05\x01\x31", 4);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
|
||||
}
|
||||
// YYYYMMDD
|
||||
payload.append(convertNumberToHex(d.year/100)); // 20
|
||||
payload.append(convertNumberToHex(d.year - 100*(d.year/100))); // 21
|
||||
payload.append(convertNumberToHex(d.month));
|
||||
payload.append(convertNumberToHex(d.day));
|
||||
//qDebug(logRig()) << "Setting date to this: ";
|
||||
//printHex(payload);
|
||||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::setUTCOffset(timekind t)
|
||||
{
|
||||
QByteArray payload;
|
||||
|
||||
switch(rigCaps.model)
|
||||
{
|
||||
case model705:
|
||||
payload.setRawData("\x1A\x05\x01\x70", 4);
|
||||
break;
|
||||
case model7300:
|
||||
payload.setRawData("\x1A\x05\x00\x96", 4);
|
||||
break;
|
||||
case model7610:
|
||||
payload.setRawData("\x1A\x05\x01\x62", 4);
|
||||
break;
|
||||
case model7700:
|
||||
payload.setRawData("\x1A\x05\x00\x61", 4);
|
||||
break;
|
||||
case model7850:
|
||||
// Clock 1:
|
||||
payload.setRawData("\x1A\x05\x00\x99", 4);
|
||||
break;
|
||||
case model9700:
|
||||
payload.setRawData("\x1A\x05\x01\x84", 4);
|
||||
break;
|
||||
case modelR8600:
|
||||
payload.setRawData("\x1A\x05\x01\x35", 4);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
|
||||
}
|
||||
payload.append(convertNumberToHex(t.hours));
|
||||
payload.append(convertNumberToHex(t.minutes));
|
||||
payload.append((unsigned char)t.isMinus);
|
||||
//qDebug(logRig()) << "Setting UTC Offset to this: ";
|
||||
//printHex(payload);
|
||||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
unsigned char rigCommander::convertNumberToHex(unsigned char num)
|
||||
{
|
||||
// Two digit only
|
||||
if(num > 99)
|
||||
{
|
||||
qInfo(logRig()) << "Invalid numeric conversion from num " << num << " to hex.";
|
||||
return 0xFA;
|
||||
}
|
||||
unsigned char result = 0;
|
||||
result = (num/10) << 4;
|
||||
result |= (num - 10*(num/10));
|
||||
qDebug(logRig()) << "Converting number: " << num << " to hex: " + QString("0x%1").arg(result, 2, 16, QChar('0'));
|
||||
return result;
|
||||
}
|
||||
|
||||
void rigCommander::sendLevelCmd(unsigned char levAddr, unsigned char level)
|
||||
{
|
||||
QByteArray payload("\x14");
|
||||
|
@ -2663,6 +2818,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.preamps.push_back('\x00');
|
||||
|
||||
rigCaps.hasAntennaSel = false;
|
||||
rigCaps.hasRXAntenna = false;
|
||||
|
||||
rigCaps.hasTransmit = true;
|
||||
rigCaps.hasPTTCommand = true;
|
||||
|
@ -2799,6 +2955,29 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.bsr[band2m] = 0x01;
|
||||
rigCaps.modes = commonModes;
|
||||
break;
|
||||
case model7600:
|
||||
rigCaps.modelName = QString("IC-7600");
|
||||
rigCaps.hasSpectrum = false;
|
||||
rigCaps.inputs.append(inputACC);
|
||||
rigCaps.inputs.append(inputUSB);
|
||||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.hasCTCSS = false;
|
||||
rigCaps.hasDTCS = false;
|
||||
rigCaps.attenuators.insert(rigCaps.attenuators.end(), {0x00, 0x06, 0x12, 0x18});
|
||||
rigCaps.preamps.push_back('\x01');
|
||||
rigCaps.preamps.push_back('\x02');
|
||||
rigCaps.antennas = {0x00, 0x01};
|
||||
rigCaps.bands = standardHF;
|
||||
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")});
|
||||
break;
|
||||
case model7610:
|
||||
rigCaps.modelName = QString("IC-7610");
|
||||
rigCaps.hasSpectrum = true;
|
||||
|
@ -2827,6 +3006,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.bands.push_back(band630m);
|
||||
rigCaps.bands.push_back(band2200m);
|
||||
rigCaps.modes = commonModes;
|
||||
rigCaps.hasRXAntenna = true;
|
||||
break;
|
||||
case model7850:
|
||||
rigCaps.modelName = QString("IC-785x");
|
||||
|
@ -2857,6 +3037,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.modes = commonModes;
|
||||
rigCaps.modes.insert(rigCaps.modes.end(), {createMode(modePSK, 0x12, "PSK"),
|
||||
createMode(modePSK_R, 0x13, "PSK-R")});
|
||||
rigCaps.hasRXAntenna = true;
|
||||
break;
|
||||
case model705:
|
||||
rigCaps.modelName = QString("IC-705");
|
||||
|
@ -3122,6 +3303,7 @@ void rigCommander::determineRigCaps()
|
|||
break;
|
||||
}
|
||||
haveRigCaps = true;
|
||||
|
||||
if(lookingForRig)
|
||||
{
|
||||
lookingForRig = false;
|
||||
|
@ -3548,11 +3730,11 @@ void rigCommander::setPreamp(unsigned char pre)
|
|||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
void rigCommander::setAntenna(unsigned char ant)
|
||||
void rigCommander::setAntenna(unsigned char ant, bool rx)
|
||||
{
|
||||
QByteArray payload("\x12");
|
||||
payload.append(ant);
|
||||
payload.append("\x00"); // 0x00 = use for TX and RX
|
||||
payload.append((unsigned char)rx); // 0x00 = use for TX and RX
|
||||
prepDataAndSend(payload);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,19 @@
|
|||
#define compCivAddr 0xE1
|
||||
|
||||
enum meterKind {
|
||||
meterNone=0,
|
||||
meterS,
|
||||
meterCenter,
|
||||
meterSWR,
|
||||
meterPower,
|
||||
meterALC,
|
||||
meterComp,
|
||||
meterVoltage,
|
||||
meterCurrent
|
||||
meterCurrent,
|
||||
meterRxdB,
|
||||
meterTxMod,
|
||||
meterRxAudio,
|
||||
meterLatency
|
||||
};
|
||||
|
||||
enum spectrumMode {
|
||||
|
@ -41,6 +47,18 @@ struct freqt {
|
|||
double MHzDouble;
|
||||
};
|
||||
|
||||
struct datekind {
|
||||
uint16_t year;
|
||||
unsigned char month;
|
||||
unsigned char day;
|
||||
};
|
||||
|
||||
struct timekind {
|
||||
unsigned char hours;
|
||||
unsigned char minutes;
|
||||
bool isMinus;
|
||||
};
|
||||
|
||||
struct rigStateStruct {
|
||||
freqt vfoAFreq;
|
||||
freqt vfoBFreq;
|
||||
|
@ -140,7 +158,7 @@ public slots:
|
|||
void getAntenna();
|
||||
void setAttenuator(unsigned char att);
|
||||
void setPreamp(unsigned char pre);
|
||||
void setAntenna(unsigned char ant);
|
||||
void setAntenna(unsigned char ant, bool rx);
|
||||
|
||||
// Repeater:
|
||||
void setDuplexMode(duplexMode dm);
|
||||
|
@ -207,6 +225,7 @@ public slots:
|
|||
|
||||
// Meters:
|
||||
void getSMeter();
|
||||
void getCenterMeter();
|
||||
void getRFPowerMeter();
|
||||
void getSWRMeter();
|
||||
void getALCMeter();
|
||||
|
@ -226,6 +245,12 @@ public slots:
|
|||
void setRefAdjustCourse(unsigned char level);
|
||||
void setRefAdjustFine(unsigned char level);
|
||||
|
||||
// Time and Date:
|
||||
void setTime(timekind t);
|
||||
void setDate(datekind d);
|
||||
void setUTCOffset(timekind t);
|
||||
|
||||
|
||||
// Satellite:
|
||||
void setSatelliteMode(bool enabled);
|
||||
void getSatelliteMode();
|
||||
|
@ -326,7 +351,7 @@ signals:
|
|||
void haveATUStatus(unsigned char status);
|
||||
void haveAttenuator(unsigned char att);
|
||||
void havePreamp(unsigned char pre);
|
||||
void haveAntenna(unsigned char ant);
|
||||
void haveAntenna(unsigned char ant,bool rx);
|
||||
|
||||
// Rig State
|
||||
void stateInfo(rigStateStruct* state);
|
||||
|
@ -350,6 +375,7 @@ private:
|
|||
QByteArray makeFreqPayload(freqt freq);
|
||||
QByteArray encodeTone(quint16 tone, bool tinv, bool rinv);
|
||||
QByteArray encodeTone(quint16 tone);
|
||||
unsigned char convertNumberToHex(unsigned char num);
|
||||
quint16 decodeTone(QByteArray eTone);
|
||||
quint16 decodeTone(QByteArray eTone, bool &tinv, bool &rinv);
|
||||
|
||||
|
|
|
@ -122,6 +122,8 @@ struct rigCapabilities {
|
|||
bool hasAntennaSel;
|
||||
bool hasDataModes;
|
||||
|
||||
bool hasRXAntenna;
|
||||
|
||||
std::vector <unsigned char> attenuators;
|
||||
std::vector <unsigned char> preamps;
|
||||
std::vector <unsigned char> antennas;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
#include "transceiveradjustments.h"
|
||||
#include "ui_transceiveradjustments.h"
|
||||
|
||||
transceiverAdjustments::transceiverAdjustments(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::transceiverAdjustments)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
// request level updates
|
||||
|
||||
}
|
||||
|
||||
transceiverAdjustments::~transceiverAdjustments()
|
||||
{
|
||||
delete ui;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef TRANSCEIVERADJUSTMENTS_H
|
||||
#define TRANSCEIVERADJUSTMENTS_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class transceiverAdjustments;
|
||||
}
|
||||
|
||||
class transceiverAdjustments : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit transceiverAdjustments(QWidget *parent = 0);
|
||||
~transceiverAdjustments();
|
||||
|
||||
private:
|
||||
Ui::transceiverAdjustments *ui;
|
||||
};
|
||||
|
||||
#endif // TRANSCEIVERADJUSTMENTS_H
|
|
@ -0,0 +1,329 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>transceiverAdjustments</class>
|
||||
<widget class="QWidget" name="transceiverAdjustments">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>680</width>
|
||||
<height>339</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Transmitter</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string>Comp</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bass</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Trebble</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TBD</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Receiver</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bass</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Trebble</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>IF Shift</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_2">
|
||||
<property name="text">
|
||||
<string>NR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_3">
|
||||
<property name="text">
|
||||
<string>NB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QSlider" name="verticalSlider_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_4">
|
||||
<property name="text">
|
||||
<string>Notch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Bandwidth</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Low</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_2"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>High</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_3"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -195,7 +195,7 @@ void udpHandler::dataReceived()
|
|||
if (txSetup.codec == 0) {
|
||||
txString = "(no tx)";
|
||||
}
|
||||
emit haveNetworkStatus(QString("<pre>%1 rx latency: %2 ms / rtt: %3 ms / loss: %4/%5</pre>").arg(txString).arg(tempLatency).arg(latency, 3).arg(totallost, 3).arg(totalsent, 3));
|
||||
emit haveNetworkStatus(QString("<pre>%1 rx latency: %2 / rtt: %3 ms / loss: %4/%5</pre>").arg(txString).arg(tempLatency).arg(latency, 3).arg(totallost, 3).arg(totalsent, 3));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1142,6 +1142,10 @@ void udpBase::dataReceived(QByteArray r)
|
|||
{
|
||||
rxBufferMutex.lock();
|
||||
if (rxSeqBuf.isEmpty()) {
|
||||
if (rxSeqBuf.size() > 400)
|
||||
{
|
||||
rxSeqBuf.erase(rxSeqBuf.begin());
|
||||
}
|
||||
rxSeqBuf.insert(in->seq, QTime::currentTime());
|
||||
}
|
||||
else
|
||||
|
@ -1162,6 +1166,10 @@ void udpBase::dataReceived(QByteArray r)
|
|||
{
|
||||
// Add incoming packet to the received buffer and if it is in the missing buffer, remove it.
|
||||
rxSeqBuf.insert(in->seq, QTime::currentTime());
|
||||
if (rxSeqBuf.size() > 400)
|
||||
{
|
||||
rxSeqBuf.erase(rxSeqBuf.begin());
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is probably one of our missing packets!
|
||||
|
@ -1217,7 +1225,15 @@ void udpBase::sendRetransmitRequest()
|
|||
{
|
||||
// We haven't seen this missing packet before
|
||||
qDebug(logUdp()) << this->metaObject()->className() << ": Adding to missing buffer (len=" << rxMissing.size() << "): " << j;
|
||||
if (rxMissing.size() > 25)
|
||||
{
|
||||
rxMissing.erase(rxMissing.begin());
|
||||
}
|
||||
rxMissing.insert(j, 0);
|
||||
if (rxSeqBuf.size() > 400)
|
||||
{
|
||||
rxSeqBuf.erase(rxSeqBuf.begin());
|
||||
}
|
||||
rxSeqBuf.insert(j, QTime::currentTime()); // Add this missing packet to the rxbuffer as we now long about it.
|
||||
packetsLost++;
|
||||
}
|
||||
|
@ -1360,11 +1376,17 @@ void udpBase::sendTrackedPacket(QByteArray d)
|
|||
congestion = 0;
|
||||
}
|
||||
txSeqBuf.insert(sendSeq,s);
|
||||
if (txSeqBuf.size() > 400)
|
||||
{
|
||||
txSeqBuf.erase(txSeqBuf.begin());
|
||||
}
|
||||
txBufferMutex.unlock();
|
||||
} else {
|
||||
qInfo(logUdp()) << this->metaObject()->className() << ": txBuffer mutex is locked";
|
||||
}
|
||||
purgeOldEntries(); // Delete entries older than PURGE_SECONDS seconds (currently 5)
|
||||
// Stop using purgeOldEntries() as it is likely slower than just removing the earliest packet.
|
||||
//qInfo(logUdp()) << this->metaObject()->className() << "RX:" << rxSeqBuf.size() << "TX:" <<txSeqBuf.size() << "MISS:" << rxMissing.size();
|
||||
//purgeOldEntries(); // Delete entries older than PURGE_SECONDS seconds (currently 5)
|
||||
sendSeq++;
|
||||
|
||||
udpMutex.lock();
|
||||
|
|
|
@ -318,7 +318,8 @@ void udpServer::controlReceived()
|
|||
passcode(user.username, usercomp);
|
||||
QByteArray passcomp;
|
||||
passcode(user.password, passcomp);
|
||||
if (!strcmp(in->username, usercomp.constData()) && (!strcmp(in->password, user.password.toUtf8()) || !strcmp(in->password, passcomp.constData())))
|
||||
if (!user.username.trimmed().isEmpty() && !user.password.trimmed().isEmpty() && !strcmp(in->username, usercomp.constData()) &&
|
||||
(!strcmp(in->password, user.password.toUtf8()) || !strcmp(in->password, passcomp.constData())))
|
||||
{
|
||||
current->isAuthenticated = true;
|
||||
current->user = user;
|
||||
|
|
589
wfmain.cpp
589
wfmain.cpp
|
@ -26,7 +26,9 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, const QString s
|
|||
cal = new calibrationWindow();
|
||||
rpt = new repeaterSetup();
|
||||
sat = new satelliteSetup();
|
||||
trxadj = new transceiverAdjustments();
|
||||
srv = new udpServerSetup();
|
||||
abtBox = new aboutbox();
|
||||
|
||||
connect(this, SIGNAL(sendServerConfig(SERVERCONFIG)), srv, SLOT(receiveServerConfig(SERVERCONFIG)));
|
||||
connect(srv, SIGNAL(serverConfig(SERVERCONFIG, bool)), this, SLOT(serverConfigRequested(SERVERCONFIG, bool)));
|
||||
|
@ -42,6 +44,9 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, const QString s
|
|||
qRegisterMetaType<mode_info>();
|
||||
qRegisterMetaType<audioPacket>();
|
||||
qRegisterMetaType <audioSetup>();
|
||||
qRegisterMetaType <timekind>();
|
||||
qRegisterMetaType <datekind>();
|
||||
|
||||
|
||||
haveRigCaps = false;
|
||||
|
||||
|
@ -106,11 +111,33 @@ wfmain::~wfmain()
|
|||
void wfmain::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
// Are you sure?
|
||||
QMessageBox::StandardButton resBtn = QMessageBox::question( this, QString("Confirm close"),
|
||||
tr("Are you sure you wish to exit?\n"),
|
||||
QMessageBox::No | QMessageBox::Yes,
|
||||
QMessageBox::Yes);
|
||||
if (resBtn == QMessageBox::Yes) {
|
||||
if (!prefs.confirmExit) {
|
||||
QApplication::exit();
|
||||
}
|
||||
QCheckBox *cb = new QCheckBox("Don't ask me again");
|
||||
QMessageBox msgbox;
|
||||
msgbox.setText("Are you sure you wish to exit?\n");
|
||||
msgbox.setIcon(QMessageBox::Icon::Question);
|
||||
QAbstractButton *yesButton = msgbox.addButton(QMessageBox::Yes);
|
||||
msgbox.addButton(QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::Yes);
|
||||
msgbox.setCheckBox(cb);
|
||||
|
||||
QObject::connect(cb, &QCheckBox::stateChanged, [this](int state){
|
||||
if (static_cast<Qt::CheckState>(state) == Qt::CheckState::Checked) {
|
||||
prefs.confirmExit=false;
|
||||
} else {
|
||||
prefs.confirmExit=true;
|
||||
}
|
||||
settings->beginGroup("Interface");
|
||||
settings->setValue("ConfirmExit", this->prefs.confirmExit);
|
||||
settings->endGroup();
|
||||
settings->sync();
|
||||
});
|
||||
|
||||
msgbox.exec();
|
||||
|
||||
if (msgbox.clickedButton() == yesButton) {
|
||||
QApplication::exit();
|
||||
} else {
|
||||
event->ignore();
|
||||
|
@ -180,9 +207,9 @@ void wfmain::openRig()
|
|||
}
|
||||
usingLAN = false;
|
||||
emit sendCommSetup(prefs.radioCIVAddr, serialPortRig, prefs.serialPortBaud,prefs.virtualSerialPort);
|
||||
ui->statusBar->showMessage(QString("Connecting to rig using serial port ").append(serialPortRig), 1000);
|
||||
}
|
||||
|
||||
ui->statusBar->showMessage(QString("Connecting to rig using serial port ").append(serialPortRig), 1000);
|
||||
|
||||
|
||||
}
|
||||
|
@ -312,13 +339,13 @@ void wfmain::rigConnections()
|
|||
connect(rig, SIGNAL(haveRigID(rigCapabilities)), this, SLOT(receiveRigID(rigCapabilities)));
|
||||
connect(this, SIGNAL(setAttenuator(unsigned char)), rig, SLOT(setAttenuator(unsigned char)));
|
||||
connect(this, SIGNAL(setPreamp(unsigned char)), rig, SLOT(setPreamp(unsigned char)));
|
||||
connect(this, SIGNAL(setAntenna(unsigned char)), rig, SLOT(setAntenna(unsigned char)));
|
||||
connect(this, SIGNAL(setAntenna(unsigned char, bool)), rig, SLOT(setAntenna(unsigned char, bool)));
|
||||
connect(this, SIGNAL(getPreamp()), rig, SLOT(getPreamp()));
|
||||
connect(rig, SIGNAL(havePreamp(unsigned char)), this, SLOT(receivePreamp(unsigned char)));
|
||||
connect(this, SIGNAL(getAttenuator()), rig, SLOT(getAttenuator()));
|
||||
connect(rig, SIGNAL(haveAttenuator(unsigned char)), this, SLOT(receiveAttenuator(unsigned char)));
|
||||
connect(this, SIGNAL(getAntenna()), rig, SLOT(getAntenna()));
|
||||
//connect(rig, SIGNAL(haveAntenna(unsigned char)), this, SLOT(receiveAntennaSel(unsigned char)));
|
||||
connect(rig, SIGNAL(haveAntenna(unsigned char,bool)), this, SLOT(receiveAntennaSel(unsigned char,bool)));
|
||||
|
||||
|
||||
// Speech (emitted from rig speaker)
|
||||
|
@ -334,6 +361,11 @@ void wfmain::rigConnections()
|
|||
connect(cal, SIGNAL(setRefAdjustCourse(unsigned char)), rig, SLOT(setRefAdjustCourse(unsigned char)));
|
||||
connect(cal, SIGNAL(setRefAdjustFine(unsigned char)), rig, SLOT(setRefAdjustFine(unsigned char)));
|
||||
|
||||
// Date and Time:
|
||||
connect(this, SIGNAL(setTime(timekind)), rig, SLOT(setTime(timekind)));
|
||||
connect(this, SIGNAL(setDate(datekind)), rig, SLOT(setDate(datekind)));
|
||||
connect(this, SIGNAL(setUTCOffset(timekind)), rig, SLOT(setUTCOffset(timekind)));
|
||||
|
||||
}
|
||||
|
||||
//void wfmain::removeRigConnections()
|
||||
|
@ -629,6 +661,32 @@ void wfmain::setupMainUI()
|
|||
ui->wfthemeCombo->addItem("Spectrum", QCPColorGradient::gpSpectrum);
|
||||
ui->wfthemeCombo->addItem("Candy", QCPColorGradient::gpCandy);
|
||||
|
||||
ui->meter2selectionCombo->addItem("None", meterNone);
|
||||
ui->meter2selectionCombo->addItem("SWR", meterSWR);
|
||||
ui->meter2selectionCombo->addItem("ALC", meterALC);
|
||||
ui->meter2selectionCombo->addItem("Compression", meterComp);
|
||||
ui->meter2selectionCombo->addItem("Voltage", meterVoltage);
|
||||
ui->meter2selectionCombo->addItem("Current", meterCurrent);
|
||||
ui->meter2selectionCombo->addItem("Center", meterCenter);
|
||||
ui->meter2Widget->hide();
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
// Experimental feature:
|
||||
ui->meter2selectionCombo->show();
|
||||
ui->secondaryMeterSelectionLabel->show();
|
||||
#else
|
||||
ui->meter2selectionCombo->hide();
|
||||
ui->secondaryMeterSelectionLabel->hide();
|
||||
#endif
|
||||
|
||||
// Future ideas:
|
||||
//ui->meter2selectionCombo->addItem("Transmit Audio", meterTxMod);
|
||||
//ui->meter2selectionCombo->addItem("Receive Audio", meterRxAudio);
|
||||
//ui->meter2selectionCombo->addItem("Latency", meterLatency);
|
||||
|
||||
|
||||
|
||||
|
||||
spans << "2.5k" << "5.0k" << "10k" << "25k";
|
||||
spans << "50k" << "100k" << "250k" << "500k";
|
||||
ui->scopeBWCombo->insertItems(0, spans);
|
||||
|
@ -686,9 +744,6 @@ void wfmain::setupMainUI()
|
|||
rigName->setText("NONE");
|
||||
rigName->setFixedWidth(50);
|
||||
|
||||
SMeterReadings.fill(0,30);
|
||||
powerMeterReadings.fill(0,30);
|
||||
|
||||
freq.MHzDouble = 0.0;
|
||||
freq.Hz = 0;
|
||||
oldFreqDialVal = ui->freqDial->value();
|
||||
|
@ -832,6 +887,11 @@ void wfmain::setInitialTiming()
|
|||
pttTimer->setInterval(180*1000); // 3 minute max transmit time in ms
|
||||
pttTimer->setSingleShot(true);
|
||||
connect(pttTimer, SIGNAL(timeout()), this, SLOT(handlePttLimit()));
|
||||
|
||||
timeSync = new QTimer(this);
|
||||
connect(timeSync, SIGNAL(timeout()), this, SLOT(setRadioTimeDateSend()));
|
||||
waitingToSetTimeDate = false;
|
||||
lastFreqCmdTime_ms = QDateTime::currentMSecsSinceEpoch() - 5000; // 5 seconds ago
|
||||
}
|
||||
|
||||
void wfmain::setServerToPrefs()
|
||||
|
@ -877,6 +937,18 @@ void wfmain::setUIToPrefs()
|
|||
ui->drawPeakChk->setChecked(prefs.drawPeaks);
|
||||
on_drawPeakChk_clicked(prefs.drawPeaks);
|
||||
drawPeaks = prefs.drawPeaks;
|
||||
|
||||
ui->wfAntiAliasChk->setChecked(prefs.wfAntiAlias);
|
||||
on_wfAntiAliasChk_clicked(prefs.wfAntiAlias);
|
||||
|
||||
ui->wfInterpolateChk->setChecked(prefs.wfInterpolate);
|
||||
on_wfInterpolateChk_clicked(prefs.wfInterpolate);
|
||||
|
||||
ui->wfLengthSlider->setValue(prefs.wflength);
|
||||
prepareWf(prefs.wflength);
|
||||
|
||||
ui->wfthemeCombo->setCurrentIndex(ui->wfthemeCombo->findData(prefs.wftheme));
|
||||
colorMap->setGradient(static_cast<QCPColorGradient::GradientPreset>(prefs.wftheme));
|
||||
}
|
||||
|
||||
void wfmain::setAudioDevicesUI()
|
||||
|
@ -1139,6 +1211,8 @@ void wfmain::setDefPrefs()
|
|||
defPrefs.useDarkMode = true;
|
||||
defPrefs.useSystemTheme = false;
|
||||
defPrefs.drawPeaks = true;
|
||||
defPrefs.wfAntiAlias = false;
|
||||
defPrefs.wfInterpolate = true;
|
||||
defPrefs.stylesheetPath = QString("qdarkstyle/style.qss");
|
||||
defPrefs.radioCIVAddr = 0x00; // previously was 0x94 for 7300.
|
||||
defPrefs.serialPortRadio = QString("auto");
|
||||
|
@ -1148,6 +1222,11 @@ void wfmain::setDefPrefs()
|
|||
defPrefs.enableRigCtlD = false;
|
||||
defPrefs.rigCtlPort = 4533;
|
||||
defPrefs.virtualSerialPort = QString("none");
|
||||
defPrefs.localAFgain = 255;
|
||||
defPrefs.wflength = 160;
|
||||
defPrefs.wftheme = static_cast<int>(QCPColorGradient::gpJet);
|
||||
defPrefs.confirmExit = true;
|
||||
defPrefs.confirmPowerOff = true;
|
||||
|
||||
udpDefPrefs.ipAddress = QString("");
|
||||
udpDefPrefs.controlLANPort = 50001;
|
||||
|
@ -1156,7 +1235,6 @@ void wfmain::setDefPrefs()
|
|||
udpDefPrefs.username = QString("");
|
||||
udpDefPrefs.password = QString("");
|
||||
udpDefPrefs.clientName = QHostInfo::localHostName();
|
||||
|
||||
}
|
||||
|
||||
void wfmain::loadSettings()
|
||||
|
@ -1169,13 +1247,20 @@ void wfmain::loadSettings()
|
|||
prefs.useFullScreen = settings->value("UseFullScreen", defPrefs.useFullScreen).toBool();
|
||||
prefs.useDarkMode = settings->value("UseDarkMode", defPrefs.useDarkMode).toBool();
|
||||
prefs.useSystemTheme = settings->value("UseSystemTheme", defPrefs.useSystemTheme).toBool();
|
||||
prefs.wftheme = settings->value("WFTheme", defPrefs.wftheme).toInt();
|
||||
prefs.drawPeaks = settings->value("DrawPeaks", defPrefs.drawPeaks).toBool();
|
||||
prefs.wfAntiAlias = settings->value("WFAntiAlias", defPrefs.wfAntiAlias).toBool();
|
||||
prefs.wfInterpolate = settings->value("WFInterpolate", defPrefs.wfInterpolate).toBool();
|
||||
prefs.wflength = (unsigned int) settings->value("WFLength", defPrefs.wflength).toInt();
|
||||
prefs.stylesheetPath = settings->value("StylesheetPath", defPrefs.stylesheetPath).toString();
|
||||
ui->splitter->restoreState(settings->value("splitter").toByteArray());
|
||||
|
||||
restoreGeometry(settings->value("windowGeometry").toByteArray());
|
||||
restoreState(settings->value("windowState").toByteArray());
|
||||
setWindowState(Qt::WindowActive); // Works around QT bug to returns window+keyboard focus.
|
||||
prefs.confirmExit = settings->value("ConfirmExit", defPrefs.confirmExit).toBool();
|
||||
prefs.confirmPowerOff = settings->value("ConfirmPowerOff", defPrefs.confirmPowerOff).toBool();
|
||||
|
||||
settings->endGroup();
|
||||
|
||||
// Load color schemes:
|
||||
|
@ -1253,7 +1338,8 @@ void wfmain::loadSettings()
|
|||
ui->vspCombo->setCurrentIndex(ui->vspCombo->count()-1);
|
||||
}
|
||||
|
||||
|
||||
prefs.localAFgain = (unsigned char) settings->value("localAFgain", defPrefs.localAFgain).toUInt();
|
||||
rxSetup.localAFgain = prefs.localAFgain;
|
||||
settings->endGroup();
|
||||
|
||||
// Misc. user settings (enable PTT, draw peaks, etc)
|
||||
|
@ -1309,7 +1395,7 @@ void wfmain::loadSettings()
|
|||
|
||||
txSetup.latency = settings->value("AudioTXLatency", "150").toInt();
|
||||
ui->txLatencySlider->setEnabled(ui->lanEnableBtn->isChecked());
|
||||
ui->txLatencySlider->setValue(rxSetup.latency);
|
||||
ui->txLatencySlider->setValue(txSetup.latency);
|
||||
ui->txLatencySlider->setTracking(false); // Stop it sending value on every change.
|
||||
|
||||
ui->audioSampleRateCombo->blockSignals(true);
|
||||
|
@ -1461,10 +1547,16 @@ void wfmain::saveSettings()
|
|||
settings->setValue("UseSystemTheme", prefs.useSystemTheme);
|
||||
settings->setValue("UseDarkMode", prefs.useDarkMode);
|
||||
settings->setValue("DrawPeaks", prefs.drawPeaks);
|
||||
settings->setValue("WFAntiAlias", prefs.wfAntiAlias);
|
||||
settings->setValue("WFInterpolate", prefs.wfInterpolate);
|
||||
settings->setValue("WFTheme", prefs.wftheme);
|
||||
settings->setValue("StylesheetPath", prefs.stylesheetPath);
|
||||
settings->setValue("splitter", ui->splitter->saveState());
|
||||
settings->setValue("windowGeometry", saveGeometry());
|
||||
settings->setValue("windowState", saveState());
|
||||
settings->setValue("WFLength", prefs.wflength);
|
||||
settings->setValue("ConfirmExit", prefs.confirmExit);
|
||||
settings->setValue("ConfirmPowerOff", prefs.confirmPowerOff);
|
||||
settings->endGroup();
|
||||
|
||||
// Radio and Comms: C-IV addr, port to use
|
||||
|
@ -1473,6 +1565,7 @@ void wfmain::saveSettings()
|
|||
settings->setValue("SerialPortRadio", prefs.serialPortRadio);
|
||||
settings->setValue("SerialPortBaud", prefs.serialPortBaud);
|
||||
settings->setValue("VirtualSerialPort", prefs.virtualSerialPort);
|
||||
settings->setValue("localAFgain", prefs.localAFgain);
|
||||
settings->endGroup();
|
||||
|
||||
// Misc. user settings (enable PTT, draw peaks, etc)
|
||||
|
@ -1781,7 +1874,7 @@ void wfmain::shortcutF10()
|
|||
|
||||
void wfmain::shortcutF12()
|
||||
{
|
||||
// Speak current frequency and mode via IC-7300
|
||||
// Speak current frequency and mode from the radio
|
||||
showStatusBarText("Sending speech command to radio.");
|
||||
emit sayAll();
|
||||
}
|
||||
|
@ -1797,8 +1890,8 @@ void wfmain::shortcutControlT()
|
|||
void wfmain::shortcutControlR()
|
||||
{
|
||||
// Receive
|
||||
emit setPTT(false);
|
||||
issueDelayedCommand(cmdGetPTT);
|
||||
issueCmdUniquePriority(cmdSetPTT, false);
|
||||
pttTimer->stop();
|
||||
}
|
||||
|
||||
void wfmain::shortcutControlI()
|
||||
|
@ -2238,6 +2331,7 @@ void wfmain::doCmd(commandtype cmddata)
|
|||
{
|
||||
case cmdSetFreq:
|
||||
{
|
||||
lastFreqCmdTime_ms = QDateTime::currentMSecsSinceEpoch();
|
||||
freqt f = (*std::static_pointer_cast<freqt>(data));
|
||||
emit setFrequency(f);
|
||||
break;
|
||||
|
@ -2295,6 +2389,12 @@ void wfmain::doCmd(commandtype cmddata)
|
|||
{
|
||||
bool pttrequest = (*std::static_pointer_cast<bool>(data));
|
||||
emit setPTT(pttrequest);
|
||||
if(pttrequest)
|
||||
{
|
||||
ui->meterSPoWidget->setMeterType(meterPower);
|
||||
} else {
|
||||
ui->meterSPoWidget->setMeterType(meterS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cmdSetATU:
|
||||
|
@ -2303,6 +2403,24 @@ void wfmain::doCmd(commandtype cmddata)
|
|||
emit setATU(atuOn);
|
||||
break;
|
||||
}
|
||||
case cmdSetUTCOffset:
|
||||
{
|
||||
timekind u = (*std::static_pointer_cast<timekind>(data));
|
||||
emit setUTCOffset(u);
|
||||
break;
|
||||
}
|
||||
case cmdSetTime:
|
||||
{
|
||||
timekind t = (*std::static_pointer_cast<timekind>(data));
|
||||
emit setTime(t);
|
||||
break;
|
||||
}
|
||||
case cmdSetDate:
|
||||
{
|
||||
datekind d = (*std::static_pointer_cast<datekind>(data));
|
||||
emit setDate(d);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
doCmd(cmd);
|
||||
break;
|
||||
|
@ -2454,10 +2572,18 @@ void wfmain::doCmd(cmds cmd)
|
|||
if(!amTransmitting)
|
||||
emit getMeters(meterS);
|
||||
break;
|
||||
case cmdGetCenterMeter:
|
||||
if(!amTransmitting)
|
||||
emit getMeters(meterCenter);
|
||||
break;
|
||||
case cmdGetPowerMeter:
|
||||
if(amTransmitting)
|
||||
emit getMeters(meterPower);
|
||||
break;
|
||||
case cmdGetSWRMeter:
|
||||
if(amTransmitting)
|
||||
emit getMeters(meterSWR);
|
||||
break;
|
||||
case cmdGetIdMeter:
|
||||
emit getMeters(meterCurrent);
|
||||
break;
|
||||
|
@ -2594,10 +2720,27 @@ void wfmain::issueCmd(cmds cmd, freqt f)
|
|||
commandtype cmddata;
|
||||
cmddata.cmd = cmd;
|
||||
cmddata.data = std::shared_ptr<freqt>(new freqt(f));
|
||||
//*static_cast<freqt*>(cmddata.data.get()) = f;
|
||||
delayedCmdQue.push_back(cmddata);
|
||||
}
|
||||
|
||||
void wfmain::issueCmd(cmds cmd, timekind t)
|
||||
{
|
||||
qDebug(logSystem()) << "Issuing timekind command with data: " << t.hours << " hours, " << t.minutes << " minutes, " << t.isMinus << " isMinus";
|
||||
commandtype cmddata;
|
||||
cmddata.cmd = cmd;
|
||||
cmddata.data = std::shared_ptr<timekind>(new timekind(t));
|
||||
delayedCmdQue.push_front(cmddata);
|
||||
}
|
||||
|
||||
void wfmain::issueCmd(cmds cmd, datekind d)
|
||||
{
|
||||
qDebug(logSystem()) << "Issuing datekind command with data: " << d.day << " day, " << d.month << " month, " << d.year << " year.";
|
||||
commandtype cmddata;
|
||||
cmddata.cmd = cmd;
|
||||
cmddata.data = std::shared_ptr<datekind>(new datekind(d));
|
||||
delayedCmdQue.push_front(cmddata);
|
||||
}
|
||||
|
||||
void wfmain::issueCmd(cmds cmd, int i)
|
||||
{
|
||||
commandtype cmddata;
|
||||
|
@ -2702,6 +2845,7 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
|
|||
|
||||
this->rigCaps = rigCaps;
|
||||
rigName->setText(rigCaps.modelName);
|
||||
setWindowTitle(rigCaps.modelName);
|
||||
this->spectWidth = rigCaps.spectLenMax; // used once haveRigCaps is true.
|
||||
haveRigCaps = true;
|
||||
// Added so that server receives rig capabilities.
|
||||
|
@ -2809,6 +2953,9 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
|
|||
ui->antennaSelCombo->setDisabled(true);
|
||||
}
|
||||
|
||||
ui->rxAntennaCheck->setEnabled(rigCaps.hasRXAntenna);
|
||||
ui->rxAntennaCheck->setChecked(false);
|
||||
|
||||
ui->scopeBWCombo->blockSignals(true);
|
||||
ui->scopeBWCombo->clear();
|
||||
if(rigCaps.hasSpectrum)
|
||||
|
@ -2823,14 +2970,17 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
|
|||
}
|
||||
ui->scopeBWCombo->blockSignals(false);
|
||||
|
||||
|
||||
setBandButtons();
|
||||
|
||||
ui->tuneEnableChk->setEnabled(rigCaps.hasATU);
|
||||
ui->tuneNowBtn->setEnabled(rigCaps.hasATU);
|
||||
|
||||
ui->connectBtn->setText("Disconnect"); // We must be connected now.
|
||||
prepareWf();
|
||||
prepareWf(ui->wfLengthSlider->value());
|
||||
if(usingLAN)
|
||||
{
|
||||
ui->afGainSlider->setValue(prefs.localAFgain);
|
||||
}
|
||||
// Adding these here because clearly at this point we have valid
|
||||
// rig comms. In the future, we should establish comms and then
|
||||
// do all the initial grabs. For now, this hack of adding them here and there:
|
||||
|
@ -2858,6 +3008,9 @@ void wfmain::initPeriodicCommands()
|
|||
insertSlowPeriodicCommand(cmdGetAttenuator, 128);
|
||||
insertSlowPeriodicCommand(cmdGetPTT, 128);
|
||||
insertSlowPeriodicCommand(cmdGetPreamp, 128);
|
||||
if (rigCaps.hasRXAntenna) {
|
||||
insertSlowPeriodicCommand(cmdGetAntenna, 128);
|
||||
}
|
||||
}
|
||||
|
||||
void wfmain::insertPeriodicCommand(cmds cmd, unsigned char priority)
|
||||
|
@ -2873,6 +3026,31 @@ void wfmain::insertPeriodicCommand(cmds cmd, unsigned char priority)
|
|||
}
|
||||
}
|
||||
|
||||
void wfmain::insertPeriodicCommandUnique(cmds cmd)
|
||||
{
|
||||
// Use this function to insert a non-duplicate command
|
||||
// into the fast periodic polling queue, typically
|
||||
// meter commands where high refresh rates are desirable.
|
||||
|
||||
removePeriodicCommand(cmd);
|
||||
periodicCmdQueue.push_front(cmd);
|
||||
}
|
||||
|
||||
void wfmain::removePeriodicCommand(cmds cmd)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
auto it = std::find(this->periodicCmdQueue.begin(), this->periodicCmdQueue.end(), cmd);
|
||||
if(it != periodicCmdQueue.end())
|
||||
{
|
||||
periodicCmdQueue.erase(it);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wfmain::insertSlowPeriodicCommand(cmds cmd, unsigned char priority)
|
||||
{
|
||||
// TODO: meaningful priority
|
||||
|
@ -2889,10 +3067,15 @@ void wfmain::insertSlowPeriodicCommand(cmds cmd, unsigned char priority)
|
|||
void wfmain::receiveFreq(freqt freqStruct)
|
||||
{
|
||||
|
||||
//qInfo(logSystem()) << "HEY WE GOT A Frequency: " << freqMhz;
|
||||
ui->freqLabel->setText(QString("%1").arg(freqStruct.MHzDouble, 0, 'f'));
|
||||
freq = freqStruct;
|
||||
//showStatusBarText(QString("Frequency: %1").arg(freqMhz));
|
||||
qint64 tnow_ms = QDateTime::currentMSecsSinceEpoch();
|
||||
if(tnow_ms - lastFreqCmdTime_ms > delayedCommand->interval() * 2)
|
||||
{
|
||||
ui->freqLabel->setText(QString("%1").arg(freqStruct.MHzDouble, 0, 'f'));
|
||||
freq = freqStruct;
|
||||
} else {
|
||||
qDebug(logSystem()) << "Rejecting stale frequency: " << freqStruct.Hz << " Hz, delta time ms = " << tnow_ms - lastFreqCmdTime_ms\
|
||||
<< ", tnow_ms " << tnow_ms << ", last: " << lastFreqCmdTime_ms;
|
||||
}
|
||||
}
|
||||
|
||||
void wfmain::receivePTTstatus(bool pttOn)
|
||||
|
@ -3036,20 +3219,23 @@ void wfmain::receiveSpectrumMode(spectrumMode spectMode)
|
|||
void wfmain::handlePlotDoubleClick(QMouseEvent *me)
|
||||
{
|
||||
double x;
|
||||
freqt freq;
|
||||
freqt freqGo;
|
||||
//double y;
|
||||
//double px;
|
||||
if(!freqLock)
|
||||
{
|
||||
//y = plot->yAxis->pixelToCoord(me->pos().y());
|
||||
x = plot->xAxis->pixelToCoord(me->pos().x());
|
||||
freq.Hz = x*1E6;
|
||||
freqGo.Hz = x*1E6;
|
||||
|
||||
freq.Hz = roundFrequency(freq.Hz, tsWfScrollHz);
|
||||
freqGo.Hz = roundFrequency(freqGo.Hz, tsWfScrollHz);
|
||||
freqGo.MHzDouble = (float)freqGo.Hz / 1E6;
|
||||
|
||||
//emit setFrequency(freq);
|
||||
issueCmd(cmdSetFreq, freq);
|
||||
issueDelayedCommand(cmdGetFreq);
|
||||
issueCmd(cmdSetFreq, freqGo);
|
||||
freq = freqGo;
|
||||
setUIFreq();
|
||||
//issueDelayedCommand(cmdGetFreq);
|
||||
showStatusBarText(QString("Going to %1 MHz").arg(x));
|
||||
}
|
||||
}
|
||||
|
@ -3057,7 +3243,7 @@ void wfmain::handlePlotDoubleClick(QMouseEvent *me)
|
|||
void wfmain::handleWFDoubleClick(QMouseEvent *me)
|
||||
{
|
||||
double x;
|
||||
freqt freq;
|
||||
freqt freqGo;
|
||||
//double y;
|
||||
//x = wf->xAxis->pixelToCoord(me->pos().x());
|
||||
//y = wf->yAxis->pixelToCoord(me->pos().y());
|
||||
|
@ -3065,13 +3251,15 @@ void wfmain::handleWFDoubleClick(QMouseEvent *me)
|
|||
if(!freqLock)
|
||||
{
|
||||
x = plot->xAxis->pixelToCoord(me->pos().x());
|
||||
freq.Hz = x*1E6;
|
||||
freqGo.Hz = x*1E6;
|
||||
|
||||
freq.Hz = roundFrequency(freq.Hz, tsWfScrollHz);
|
||||
freqGo.Hz = roundFrequency(freqGo.Hz, tsWfScrollHz);
|
||||
freqGo.MHzDouble = (float)freqGo.Hz / 1E6;
|
||||
|
||||
//emit setFrequency(freq);
|
||||
issueCmd(cmdSetFreq, freq);
|
||||
issueDelayedCommand(cmdGetFreq);
|
||||
issueCmd(cmdSetFreq, freqGo);
|
||||
freq = freqGo;
|
||||
setUIFreq();
|
||||
showStatusBarText(QString("Going to %1 MHz").arg(x));
|
||||
}
|
||||
}
|
||||
|
@ -3126,7 +3314,7 @@ void wfmain::handleWFScroll(QWheelEvent *we)
|
|||
//emit setFrequency(f);
|
||||
issueCmdUniquePriority(cmdSetFreq, f);
|
||||
ui->freqLabel->setText(QString("%1").arg(f.MHzDouble, 0, 'f'));
|
||||
issueDelayedCommandUnique(cmdGetFreq);
|
||||
//issueDelayedCommandUnique(cmdGetFreq);
|
||||
}
|
||||
|
||||
void wfmain::handlePlotScroll(QWheelEvent *we)
|
||||
|
@ -3245,32 +3433,32 @@ void wfmain::on_goFreqBtn_clicked()
|
|||
{
|
||||
freqt f;
|
||||
bool ok = false;
|
||||
double freq = 0;
|
||||
double freqDbl = 0;
|
||||
int KHz = 0;
|
||||
|
||||
if(ui->freqMhzLineEdit->text().contains("."))
|
||||
{
|
||||
|
||||
freq = ui->freqMhzLineEdit->text().toDouble(&ok);
|
||||
freqDbl = ui->freqMhzLineEdit->text().toDouble(&ok);
|
||||
if(ok)
|
||||
{
|
||||
f.Hz = freq*1E6;
|
||||
//emit setFrequency(f);
|
||||
issueCmd(cmdSetFreq, f);
|
||||
//issueCmdSetFreq(f);
|
||||
issueDelayedCommand(cmdGetFreq);
|
||||
f.Hz = freqDbl*1E6;
|
||||
issueCmd(cmdSetFreq, f);
|
||||
}
|
||||
} else {
|
||||
KHz = ui->freqMhzLineEdit->text().toInt(&ok);
|
||||
if(ok)
|
||||
{
|
||||
f.Hz = KHz*1E3;
|
||||
//issueCmdSetFreq(f);
|
||||
//emit setFrequency(f);
|
||||
issueCmd(cmdSetFreq, f);
|
||||
issueDelayedCommand(cmdGetFreq);
|
||||
}
|
||||
}
|
||||
if(ok)
|
||||
{
|
||||
f.MHzDouble = (float)f.Hz / 1E6;
|
||||
freq = f;
|
||||
setUIFreq();
|
||||
}
|
||||
|
||||
ui->freqMhzLineEdit->selectAll();
|
||||
freqTextSelected = true;
|
||||
|
@ -3550,17 +3738,19 @@ void wfmain::on_freqDial_valueChanged(int value)
|
|||
}
|
||||
}
|
||||
|
||||
void wfmain::receiveBandStackReg(freqt freq, char mode, char filter, bool dataOn)
|
||||
void wfmain::receiveBandStackReg(freqt freqGo, char mode, char filter, bool dataOn)
|
||||
{
|
||||
// read the band stack and apply by sending out commands
|
||||
|
||||
qInfo(logSystem()) << __func__ << "BSR received into main: Freq: " << freq.Hz << ", mode: " << (unsigned int)mode << ", filter: " << (unsigned int)filter << ", data mode: " << dataOn;
|
||||
qInfo(logSystem()) << __func__ << "BSR received into main: Freq: " << freqGo.Hz << ", mode: " << (unsigned int)mode << ", filter: " << (unsigned int)filter << ", data mode: " << dataOn;
|
||||
//emit setFrequency(freq);
|
||||
issueCmd(cmdSetFreq, freq);
|
||||
issueCmd(cmdSetFreq, freqGo);
|
||||
setModeVal = (unsigned char) mode;
|
||||
setFilterVal = (unsigned char) filter;
|
||||
|
||||
issueDelayedCommand(cmdSetModeFilter);
|
||||
freq = freqGo;
|
||||
setUIFreq();
|
||||
|
||||
if(dataOn)
|
||||
{
|
||||
|
@ -3568,8 +3758,8 @@ void wfmain::receiveBandStackReg(freqt freq, char mode, char filter, bool dataOn
|
|||
} else {
|
||||
issueDelayedCommand(cmdSetDataModeOff);
|
||||
}
|
||||
issueDelayedCommand(cmdGetFreq);
|
||||
issueDelayedCommand(cmdGetMode);
|
||||
//issueDelayedCommand(cmdGetFreq);
|
||||
//issueDelayedCommand(cmdGetMode);
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
|
||||
receiveMode((unsigned char) mode, (unsigned char) filter); // update UI
|
||||
|
@ -3737,58 +3927,9 @@ void wfmain::on_bandGenbtn_clicked()
|
|||
|
||||
void wfmain::on_aboutBtn_clicked()
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle("Abou wfview");
|
||||
msgBox.setTextFormat(Qt::RichText);
|
||||
msgBox.setWindowIcon(QIcon(":resources/wfview.png"));
|
||||
// TODO: change style of link color based on current CSS sheet.
|
||||
abtBox->show();
|
||||
|
||||
QString head = QString("<html><head></head><body>");
|
||||
QString copyright = QString("Copyright 2017-2021 Elliott H. Liggett, W6EL. All rights reserved.");
|
||||
QString nacode = QString("<br/><br/>Networking and audio code written by Phil Taylor, M0VSE");
|
||||
QString doctest = QString("<br/><br/>Testing, documentation, bug fixes, and development mentorship from<br/>Roeland Jansen, PA3MET, and Jim Nijkamp, PA8E.");
|
||||
QString ssCredit = QString("<br/><br/>Stylesheet <a href=\"https://github.com/ColinDuquesnoy/QDarkStyleSheet/tree/master/qdarkstyle\" style=\"color: cyan;\">qdarkstyle</a> used under MIT license, stored in /usr/share/wfview/stylesheets/.");
|
||||
QString rsCredit = QString("<br/><br/><a href=\"https://www.speex.org/\" style=\"color: cyan;\">Speex</a> Resample library Copyright 2003-2008 Jean-Marc Valin");
|
||||
QString website = QString("<br/><br/>Please visit <a href=\"https://wfview.org/\" style=\"color: cyan;\">https://wfview.org/</a> for the latest information.");
|
||||
QString docs = QString("<br/><br/>Be sure to check the <a href=\"https://wfview.org/wfview-user-manual/\" style=\"color: cyan;\">User Manual</a> and <a href=\"https://forum.wfview.org/\" style=\"color: cyan;\">the Forum</a> if you have any questions.");
|
||||
|
||||
QString gitcodelink = QString("<a href=\"https://gitlab.com/eliggett/wfview/-/tree/%1\" style=\"color: cyan;\">").arg(GITSHORT);
|
||||
|
||||
QString contact = QString("<br/>email the author: kilocharlie8@gmail.com or W6EL on the air!");
|
||||
|
||||
QString buildInfo = QString("<br/><br/>Build " + gitcodelink + QString(GITSHORT) + "</a> on " + QString(__DATE__) + " at " + __TIME__ + " by " + UNAME + "@" + HOST);
|
||||
QString end = QString("</body></html>");
|
||||
|
||||
QString aboutText = head + copyright + "\n" + nacode + "\n" + doctest + "\n" + ssCredit + "\n" + rsCredit + "\n";
|
||||
aboutText.append(website + "\n"+ docs + contact +"\n" + buildInfo + end);
|
||||
|
||||
msgBox.setText(aboutText);
|
||||
msgBox.exec();
|
||||
|
||||
volatile QString sxcreditcopyright = QString("Speex copyright notice:\
|
||||
Copyright (C) 2003 Jean-Marc Valin\n\
|
||||
Redistribution and use in source and binary forms, with or without\
|
||||
modification, are permitted provided that the following conditions\
|
||||
are met:\n\
|
||||
- Redistributions of source code must retain the above copyright\
|
||||
notice, this list of conditions and the following disclaimer.\n\
|
||||
- Redistributions in binary form must reproduce the above copyright\
|
||||
notice, this list of conditions and the following disclaimer in the\
|
||||
documentation and/or other materials provided with the distribution.\n\
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its\
|
||||
contributors may be used to endorse or promote products derived from\
|
||||
this software without specific prior written permission.\n\
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR\
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.");
|
||||
|
||||
}
|
||||
|
||||
|
@ -3840,7 +3981,6 @@ void wfmain::on_fRclBtn_clicked()
|
|||
setModeVal = temp.mode;
|
||||
setFilterVal = ui->modeFilterCombo->currentIndex()+1; // TODO, add to memory
|
||||
issueDelayedCommand(cmdSetModeFilter);
|
||||
issueDelayedCommand(cmdGetFreq);
|
||||
issueDelayedCommand(cmdGetMode);
|
||||
} else {
|
||||
qInfo(logSystem()) << "Could not recall preset. Valid presets are 0 through 99.";
|
||||
|
@ -3856,6 +3996,11 @@ void wfmain::on_rfGainSlider_valueChanged(int value)
|
|||
void wfmain::on_afGainSlider_valueChanged(int value)
|
||||
{
|
||||
issueCmdUniquePriority(cmdSetAfGain, (unsigned char)value);
|
||||
if(usingLAN)
|
||||
{
|
||||
rxSetup.localAFgain = (unsigned char)(value);
|
||||
prefs.localAFgain = (unsigned char)(value);
|
||||
}
|
||||
}
|
||||
|
||||
void wfmain::receiveRfGain(unsigned char level)
|
||||
|
@ -4019,7 +4164,7 @@ void wfmain::on_lanEnableBtn_clicked(bool checked)
|
|||
//ui->udpServerSetupBtn->setEnabled(false);
|
||||
if(checked)
|
||||
{
|
||||
showStatusBarText("After filling in values, press Save Settings and re-start wfview.");
|
||||
showStatusBarText("After filling in values, press Save Settings.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4216,6 +4361,57 @@ void wfmain::on_satOpsBtn_clicked()
|
|||
sat->show();
|
||||
}
|
||||
|
||||
void wfmain::setRadioTimeDatePrep()
|
||||
{
|
||||
if(!waitingToSetTimeDate)
|
||||
{
|
||||
// 1: Find the current time and date
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
now.setTime(QTime::currentTime());
|
||||
|
||||
int second = now.time().second();
|
||||
|
||||
// 2: Find how many mseconds until next minute
|
||||
int msecdelay = QTime::currentTime().msecsTo( QTime::currentTime().addSecs(60-second) );
|
||||
|
||||
// 3: Compute time and date at one minute later
|
||||
QDateTime setpoint = now.addMSecs(msecdelay); // at HMS or posibly HMS + some ms. Never under though.
|
||||
|
||||
// 4: Prepare data structs for the time at one minute later
|
||||
timesetpoint.hours = (unsigned char)setpoint.time().hour();
|
||||
timesetpoint.minutes = (unsigned char)setpoint.time().minute();
|
||||
datesetpoint.day = (unsigned char)setpoint.date().day();
|
||||
datesetpoint.month = (unsigned char)setpoint.date().month();
|
||||
datesetpoint.year = (uint16_t)setpoint.date().year();
|
||||
unsigned int utcOffsetSeconds = (unsigned int)abs(setpoint.offsetFromUtc());
|
||||
bool isMinus = setpoint.offsetFromUtc() < 0;
|
||||
utcsetting.hours = utcOffsetSeconds / 60 / 60;
|
||||
utcsetting.minutes = (utcOffsetSeconds - (utcsetting.hours*60*60) ) / 60;
|
||||
utcsetting.isMinus = isMinus;
|
||||
|
||||
timeSync->setInterval(msecdelay);
|
||||
timeSync->setSingleShot(true);
|
||||
|
||||
// 5: start one-shot timer for the delta computed in #2.
|
||||
timeSync->start();
|
||||
waitingToSetTimeDate = true;
|
||||
showStatusBarText(QString("Setting time, date, and UTC offset for radio in %1 seconds.").arg(msecdelay/1000));
|
||||
}
|
||||
}
|
||||
|
||||
void wfmain::setRadioTimeDateSend()
|
||||
{
|
||||
// Issue priority commands for UTC offset, date, and time
|
||||
// UTC offset must come first, otherwise the radio may "help" and correct for any changes.
|
||||
|
||||
showStatusBarText(QString("Setting time, date, and UTC offset for radio now."));
|
||||
|
||||
issueCmd(cmdSetTime, timesetpoint);
|
||||
issueCmd(cmdSetDate, datesetpoint);
|
||||
issueCmd(cmdSetUTCOffset, utcsetting);
|
||||
waitingToSetTimeDate = false;
|
||||
}
|
||||
|
||||
void wfmain::changeSliderQuietly(QSlider *slider, int value)
|
||||
{
|
||||
slider->blockSignals(true);
|
||||
|
@ -4355,54 +4551,23 @@ void wfmain::receiveLANGain(unsigned char level)
|
|||
void wfmain::receiveMeter(meterKind inMeter, unsigned char level)
|
||||
{
|
||||
|
||||
unsigned int peak = 0;
|
||||
unsigned int sum=0;
|
||||
unsigned int average=0;
|
||||
|
||||
switch(inMeter)
|
||||
{
|
||||
case meterS:
|
||||
SMeterReadings[(smeterPos++)%SMeterReadings.length()] = level;
|
||||
for(int i=0; i < SMeterReadings.length(); i++)
|
||||
{
|
||||
if((unsigned char)SMeterReadings.at(i) > peak)
|
||||
peak = (unsigned char)SMeterReadings.at(i);
|
||||
sum += (unsigned char)SMeterReadings.at(i);
|
||||
}
|
||||
average = sum / SMeterReadings.length();
|
||||
ui->meterWidget->setLevels(level, peak, average);
|
||||
ui->meterWidget->repaint();
|
||||
//ui->levelIndicator->setValue((int)level);
|
||||
break;
|
||||
case meterSWR:
|
||||
//ui->levelIndicator->setValue((int)level);
|
||||
ui->meterSPoWidget->setMeterType(meterS);
|
||||
ui->meterSPoWidget->setLevel(level);
|
||||
ui->meterSPoWidget->repaint();
|
||||
break;
|
||||
case meterPower:
|
||||
powerMeterReadings[(powerMeterPos++)%powerMeterReadings.length()] = level;
|
||||
for(int i=0; i < powerMeterReadings.length(); i++)
|
||||
{
|
||||
if((unsigned char)powerMeterReadings.at(i) > peak)
|
||||
peak = (unsigned char)powerMeterReadings.at(i);
|
||||
sum += (unsigned char)powerMeterReadings.at(i);
|
||||
}
|
||||
average = sum / powerMeterReadings.length();
|
||||
ui->meterWidget->setLevels(level, peak, average);
|
||||
ui->meterWidget->update();
|
||||
//ui->levelIndicator->setValue((int)level);
|
||||
break;
|
||||
case meterALC:
|
||||
//ui->levelIndicator->setValue((int)level);
|
||||
break;
|
||||
case meterComp:
|
||||
//ui->levelIndicator->setValue((int)level);
|
||||
break;
|
||||
case meterCurrent:
|
||||
//ui->levelIndicator->setValue((int)level);
|
||||
break;
|
||||
case meterVoltage:
|
||||
//ui->levelIndicator->setValue((int)level);
|
||||
ui->meterSPoWidget->setMeterType(meterPower);
|
||||
ui->meterSPoWidget->setLevel(level);
|
||||
ui->meterSPoWidget->update();
|
||||
break;
|
||||
default:
|
||||
if(ui->meter2Widget->getMeterType() == inMeter)
|
||||
{
|
||||
ui->meter2Widget->setLevel(level);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4611,12 +4776,18 @@ void wfmain::on_preampSelCombo_activated(int index)
|
|||
void wfmain::on_antennaSelCombo_activated(int index)
|
||||
{
|
||||
unsigned char ant = (unsigned char)ui->antennaSelCombo->itemData(index).toInt();
|
||||
emit setAntenna(ant);
|
||||
emit setAntenna(ant,ui->rxAntennaCheck->isChecked());
|
||||
}
|
||||
|
||||
void wfmain::on_rxAntennaCheck_clicked(bool value)
|
||||
{
|
||||
unsigned char ant = (unsigned char)ui->antennaSelCombo->itemData(ui->antennaSelCombo->currentIndex()).toInt();
|
||||
emit setAntenna(ant, value);
|
||||
}
|
||||
void wfmain::on_wfthemeCombo_activated(int index)
|
||||
{
|
||||
colorMap->setGradient(static_cast<QCPColorGradient::GradientPreset>(ui->wfthemeCombo->itemData(index).toInt()));
|
||||
prefs.wftheme = ui->wfthemeCombo->itemData(index).toInt();
|
||||
}
|
||||
|
||||
void wfmain::receivePreamp(unsigned char pre)
|
||||
|
@ -4631,6 +4802,12 @@ void wfmain::receiveAttenuator(unsigned char att)
|
|||
ui->attSelCombo->setCurrentIndex(attindex);
|
||||
}
|
||||
|
||||
void wfmain::receiveAntennaSel(unsigned char ant, bool rx)
|
||||
{
|
||||
ui->antennaSelCombo->setCurrentIndex(ant);
|
||||
ui->rxAntennaCheck->setChecked(rx);
|
||||
}
|
||||
|
||||
void wfmain::receiveSpectrumSpan(freqt freqspan, bool isSub)
|
||||
{
|
||||
if(!isSub)
|
||||
|
@ -4728,10 +4905,37 @@ void wfmain::on_rigPowerOnBtn_clicked()
|
|||
|
||||
void wfmain::on_rigPowerOffBtn_clicked()
|
||||
{
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(this, "Power", "Power down the radio?",
|
||||
QMessageBox::Yes|QMessageBox::No);
|
||||
if (reply == QMessageBox::Yes) {
|
||||
// Are you sure?
|
||||
if (!prefs.confirmPowerOff) {
|
||||
powerRigOff();
|
||||
return;
|
||||
}
|
||||
QCheckBox* cb = new QCheckBox("Don't ask me again");
|
||||
QMessageBox msgbox;
|
||||
msgbox.setWindowTitle("Power");
|
||||
msgbox.setText("Power down the radio?\n");
|
||||
msgbox.setIcon(QMessageBox::Icon::Question);
|
||||
QAbstractButton* yesButton = msgbox.addButton(QMessageBox::Yes);
|
||||
msgbox.addButton(QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::Yes);
|
||||
msgbox.setCheckBox(cb);
|
||||
|
||||
QObject::connect(cb, &QCheckBox::stateChanged, [this](int state) {
|
||||
if (static_cast<Qt::CheckState>(state) == Qt::CheckState::Checked) {
|
||||
prefs.confirmPowerOff = false;
|
||||
}
|
||||
else {
|
||||
prefs.confirmPowerOff = true;
|
||||
}
|
||||
settings->beginGroup("Interface");
|
||||
settings->setValue("ConfirmPowerOff", this->prefs.confirmPowerOff);
|
||||
settings->endGroup();
|
||||
settings->sync();
|
||||
});
|
||||
|
||||
msgbox.exec();
|
||||
|
||||
if (msgbox.clickedButton() == yesButton) {
|
||||
powerRigOff();
|
||||
}
|
||||
}
|
||||
|
@ -4949,6 +5153,7 @@ void wfmain::on_baudRateCombo_activated(int index)
|
|||
|
||||
void wfmain::on_wfLengthSlider_valueChanged(int value)
|
||||
{
|
||||
prefs.wflength = (unsigned int)(value);
|
||||
prepareWf(value);
|
||||
}
|
||||
|
||||
|
@ -4966,12 +5171,92 @@ void wfmain::on_pollingBtn_clicked()
|
|||
}
|
||||
}
|
||||
|
||||
void wfmain::on_wfAntiAliasChk_clicked(bool checked)
|
||||
{
|
||||
colorMap->setAntialiased(checked);
|
||||
prefs.wfAntiAlias = checked;
|
||||
}
|
||||
|
||||
void wfmain::on_wfInterpolateChk_clicked(bool checked)
|
||||
{
|
||||
colorMap->setInterpolate(checked);
|
||||
prefs.wfInterpolate = checked;
|
||||
}
|
||||
|
||||
wfmain::cmds wfmain::meterKindToMeterCommand(meterKind m)
|
||||
{
|
||||
cmds c;
|
||||
switch(m)
|
||||
{
|
||||
case meterNone:
|
||||
c = cmdNone;
|
||||
break;
|
||||
case meterS:
|
||||
c = cmdGetSMeter;
|
||||
break;
|
||||
case meterCenter:
|
||||
c = cmdGetCenterMeter;
|
||||
break;
|
||||
case meterPower:
|
||||
c = cmdGetPowerMeter;
|
||||
break;
|
||||
case meterSWR:
|
||||
c = cmdGetSWRMeter;
|
||||
break;
|
||||
case meterALC:
|
||||
c = cmdGetALCMeter;
|
||||
break;
|
||||
case meterComp:
|
||||
c = cmdGetCompMeter;
|
||||
break;
|
||||
case meterCurrent:
|
||||
c = cmdGetIdMeter;
|
||||
break;
|
||||
case meterVoltage:
|
||||
c = cmdGetVdMeter;
|
||||
break;
|
||||
default:
|
||||
c = cmdNone;
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void wfmain::on_meter2selectionCombo_activated(int index)
|
||||
{
|
||||
meterKind newMeterType;
|
||||
meterKind oldMeterType;
|
||||
newMeterType = static_cast<meterKind>(ui->meter2selectionCombo->currentData().toInt());
|
||||
oldMeterType = ui->meter2Widget->getMeterType();
|
||||
|
||||
if(newMeterType == oldMeterType)
|
||||
return;
|
||||
|
||||
cmds newCmd = meterKindToMeterCommand(newMeterType);
|
||||
cmds oldCmd = meterKindToMeterCommand(oldMeterType);
|
||||
|
||||
removePeriodicCommand(oldCmd);
|
||||
|
||||
if(newMeterType==meterNone)
|
||||
{
|
||||
ui->meter2Widget->hide();
|
||||
} else {
|
||||
ui->meter2Widget->show();
|
||||
ui->meter2Widget->setMeterType(newMeterType);
|
||||
insertPeriodicCommandUnique(newCmd);
|
||||
}
|
||||
(void)index;
|
||||
}
|
||||
|
||||
// --- DEBUG FUNCTION ---
|
||||
void wfmain::on_debugBtn_clicked()
|
||||
{
|
||||
qInfo(logSystem()) << "Debug button pressed.";
|
||||
freqt f;
|
||||
f.Hz = 14290000;
|
||||
issueCmd(cmdSetFreq, f);
|
||||
}
|
||||
//trxadj->show();
|
||||
//setRadioTimeDatePrep();
|
||||
//wf->setInteraction(QCP::iRangeZoom, true);
|
||||
//wf->setInteraction(QCP::iRangeDrag, true);
|
||||
|
||||
}
|
||||
|
|
64
wfmain.h
64
wfmain.h
|
@ -21,10 +21,12 @@
|
|||
#include "calibrationwindow.h"
|
||||
#include "repeatersetup.h"
|
||||
#include "satellitesetup.h"
|
||||
#include "transceiveradjustments.h"
|
||||
#include "udpserversetup.h"
|
||||
#include "udpserver.h"
|
||||
#include "qledlabel.h"
|
||||
#include "rigctld.h"
|
||||
#include "aboutbox.h"
|
||||
|
||||
#include <qcustomplot.h>
|
||||
#include <qserialportinfo.h>
|
||||
|
@ -118,11 +120,16 @@ signals:
|
|||
void getAntenna();
|
||||
void setAttenuator(unsigned char att);
|
||||
void setPreamp(unsigned char pre);
|
||||
void setAntenna(unsigned char ant);
|
||||
void setAntenna(unsigned char ant, bool rx);
|
||||
void startATU();
|
||||
void setATU(bool atuEnabled);
|
||||
void getATUStatus();
|
||||
|
||||
// Time and date:
|
||||
void setTime(timekind t);
|
||||
void setDate(datekind d);
|
||||
void setUTCOffset(timekind t);
|
||||
|
||||
void getRigID(); // this is the model of the rig
|
||||
void getRigCIV(); // get the rig's CIV addr
|
||||
void spectOutputEnable();
|
||||
|
@ -227,7 +234,7 @@ private slots:
|
|||
void receiveATUStatus(unsigned char atustatus);
|
||||
void receivePreamp(unsigned char pre);
|
||||
void receiveAttenuator(unsigned char att);
|
||||
//void receiveAntennaSel(unsigned char ant);
|
||||
void receiveAntennaSel(unsigned char ant, bool rx);
|
||||
void receiveRigID(rigCapabilities rigCaps);
|
||||
void receiveFoundRigID(rigCapabilities rigCaps);
|
||||
void receiveSerialPortError(QString port, QString errorText);
|
||||
|
@ -243,6 +250,9 @@ private slots:
|
|||
void serverConfigRequested(SERVERCONFIG conf, bool store);
|
||||
void receiveBaudRate(quint32 baudrate);
|
||||
|
||||
void setRadioTimeDateSend();
|
||||
|
||||
|
||||
// void on_getFreqBtn_clicked();
|
||||
|
||||
// void on_getModeBtn_clicked();
|
||||
|
@ -418,6 +428,8 @@ private slots:
|
|||
|
||||
void on_antennaSelCombo_activated(int index);
|
||||
|
||||
void on_rxAntennaCheck_clicked(bool value);
|
||||
|
||||
void on_wfthemeCombo_activated(int index);
|
||||
|
||||
void on_rigPowerOnBtn_clicked();
|
||||
|
@ -454,6 +466,12 @@ private slots:
|
|||
|
||||
void on_pollingBtn_clicked();
|
||||
|
||||
void on_wfAntiAliasChk_clicked(bool checked);
|
||||
|
||||
void on_wfInterpolateChk_clicked(bool checked);
|
||||
|
||||
void on_meter2selectionCombo_activated(int index);
|
||||
|
||||
private:
|
||||
Ui::wfmain *ui;
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
@ -560,12 +578,6 @@ private:
|
|||
|
||||
QByteArray spectrumPeaks;
|
||||
|
||||
QByteArray powerMeterReadings;
|
||||
int powerMeterPos = 0;
|
||||
|
||||
QByteArray SMeterReadings;
|
||||
int smeterPos=0;
|
||||
|
||||
QVector <QByteArray> wfimage;
|
||||
unsigned int wfLengthMax;
|
||||
|
||||
|
@ -588,8 +600,9 @@ private:
|
|||
cmdGetSql, cmdSetSql, cmdGetATUStatus, cmdSetATU, cmdStartATU, cmdGetSpectrumMode, cmdGetSpectrumSpan, cmdScopeCenterMode, cmdScopeFixedMode, cmdGetPTT, cmdSetPTT,
|
||||
cmdGetTxPower, cmdSetTxPower, cmdGetMicGain, cmdSetMicGain, cmdSetModLevel, cmdGetSpectrumRefLevel, cmdGetDuplexMode, cmdGetModInput, cmdGetModDataInput,
|
||||
cmdGetCurrentModLevel, cmdStartRegularPolling, cmdStopRegularPolling, cmdQueNormalSpeed,
|
||||
cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetPowerMeter, cmdGetALCMeter, cmdGetCompMeter, cmdGetTxRxMeter,
|
||||
cmdGetTone, cmdGetTSQL, cmdGetDTCS, cmdGetRptAccessMode, cmdGetPreamp, cmdGetAttenuator, cmdGetAntenna};
|
||||
cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetCenterMeter, cmdGetPowerMeter, cmdGetSWRMeter, cmdGetALCMeter, cmdGetCompMeter, cmdGetTxRxMeter,
|
||||
cmdGetTone, cmdGetTSQL, cmdGetDTCS, cmdGetRptAccessMode, cmdGetPreamp, cmdGetAttenuator, cmdGetAntenna,
|
||||
cmdSetTime, cmdSetDate, cmdSetUTCOffset};
|
||||
|
||||
struct commandtype {
|
||||
cmds cmd;
|
||||
|
@ -604,6 +617,8 @@ private:
|
|||
|
||||
void issueCmd(cmds cmd, freqt f);
|
||||
void issueCmd(cmds cmd, mode_info m);
|
||||
void issueCmd(cmds cmd, timekind t);
|
||||
void issueCmd(cmds cmd, datekind d);
|
||||
void issueCmd(cmds cmd, int i);
|
||||
void issueCmd(cmds cmd, unsigned char c);
|
||||
void issueCmd(cmds cmd, char c);
|
||||
|
@ -617,6 +632,8 @@ private:
|
|||
|
||||
void removeSimilarCommand(cmds cmd);
|
||||
|
||||
qint64 lastFreqCmdTime_ms;
|
||||
|
||||
int pCmdNum = 0;
|
||||
int delayedCmdIntervalLAN_ms = 100;
|
||||
int delayedCmdIntervalSerial_ms = 100;
|
||||
|
@ -624,6 +641,14 @@ private:
|
|||
bool runPeriodicCommands;
|
||||
bool usingLAN = false;
|
||||
|
||||
// Radio time sync:
|
||||
QTimer *timeSync;
|
||||
bool waitingToSetTimeDate;
|
||||
void setRadioTimeDatePrep();
|
||||
timekind timesetpoint;
|
||||
timekind utcsetting;
|
||||
datekind datesetpoint;
|
||||
|
||||
freqMemory mem;
|
||||
struct colors {
|
||||
QColor Dark_PlotBackground;
|
||||
|
@ -655,6 +680,8 @@ private:
|
|||
bool useDarkMode;
|
||||
bool useSystemTheme;
|
||||
bool drawPeaks;
|
||||
bool wfAntiAlias;
|
||||
bool wfInterpolate;
|
||||
QString stylesheetPath;
|
||||
unsigned char radioCIVAddr;
|
||||
QString serialPortRadio;
|
||||
|
@ -666,6 +693,12 @@ private:
|
|||
quint16 rigCtlPort;
|
||||
colors colorScheme;
|
||||
QString virtualSerialPort;
|
||||
unsigned char localAFgain;
|
||||
unsigned int wflength;
|
||||
int wftheme;
|
||||
bool confirmExit;
|
||||
bool confirmPowerOff;
|
||||
// plot scheme
|
||||
} prefs;
|
||||
|
||||
preferences defPrefs;
|
||||
|
@ -707,14 +740,20 @@ private:
|
|||
|
||||
void changeModLabelAndSlider(rigInput source);
|
||||
|
||||
// Fast command queue:
|
||||
void initPeriodicCommands();
|
||||
void insertPeriodicCommand(cmds cmd, unsigned char priority);
|
||||
void insertPeriodicCommandUnique(cmds cmd);
|
||||
void removePeriodicCommand(cmds cmd);
|
||||
|
||||
void insertSlowPeriodicCommand(cmds cmd, unsigned char priority);
|
||||
void calculateTimingParameters();
|
||||
|
||||
void changeMode(mode_kind mode);
|
||||
void changeMode(mode_kind mode, bool dataOn);
|
||||
|
||||
cmds meterKindToMeterCommand(meterKind m);
|
||||
|
||||
int oldFreqDialVal;
|
||||
|
||||
rigCapabilities rigCaps;
|
||||
|
@ -737,7 +776,10 @@ private:
|
|||
calibrationWindow *cal;
|
||||
repeaterSetup *rpt;
|
||||
satelliteSetup *sat;
|
||||
transceiverAdjustments *trxadj;
|
||||
udpServerSetup *srv;
|
||||
aboutbox *abtBox;
|
||||
|
||||
|
||||
udpServer* udp = Q_NULLPTR;
|
||||
rigCtlD* rigCtl = Q_NULLPTR;
|
||||
|
@ -776,6 +818,8 @@ Q_DECLARE_METATYPE(struct udpPreferences)
|
|||
Q_DECLARE_METATYPE(struct rigStateStruct)
|
||||
Q_DECLARE_METATYPE(struct audioPacket)
|
||||
Q_DECLARE_METATYPE(struct audioSetup)
|
||||
Q_DECLARE_METATYPE(struct timekind)
|
||||
Q_DECLARE_METATYPE(struct datekind)
|
||||
Q_DECLARE_METATYPE(enum rigInput)
|
||||
Q_DECLARE_METATYPE(enum meterKind)
|
||||
Q_DECLARE_METATYPE(enum spectrumMode)
|
||||
|
|
62
wfmain.ui
62
wfmain.ui
|
@ -141,8 +141,11 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="wfthemeCombo">
|
||||
<property name="toolTip">
|
||||
<string>Waterfall color theme</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Spectrum color theme</string>
|
||||
<string>Waterfall display color theme</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string>Selects the theme for the color waterfall dispaly</string>
|
||||
|
@ -238,9 +241,18 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
||||
<layout class="QVBoxLayout" name="meterLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="meter" name="meterWidget" native="true">
|
||||
<widget class="meter" name="meterSPoWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -255,6 +267,9 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="meter" name="meter2Widget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -990,6 +1005,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="rxAntennaCheck">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -2051,6 +2076,23 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="wfAntiAliasChk">
|
||||
<property name="text">
|
||||
<string>Anti-Alias Waterfall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="wfInterpolateChk">
|
||||
<property name="text">
|
||||
<string>Interpolate Waterfall</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fullScreenChk">
|
||||
<property name="text">
|
||||
|
@ -2179,6 +2221,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="secondaryMeterSelectionLabel">
|
||||
<property name="text">
|
||||
<string>Secondary Meter Selection:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="meter2selectionCombo"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
|
@ -2678,7 +2730,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="label_33">
|
||||
<property name="text">
|
||||
<string>Please note: Changing CI-V Address, Serial Device, and Baud rate requires pressing "Save Settings", closing wfview, and re-opening. </string>
|
||||
<string>Please note: Changing the built-in network server requires pressing "Save Settings", closing wfview, and re-opening. </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -2730,7 +2782,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>934</width>
|
||||
<height>22</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
13
wfview.pro
13
wfview.pro
|
@ -132,7 +132,9 @@ SOURCES += main.cpp\
|
|||
resampler/resample.c \
|
||||
repeatersetup.cpp \
|
||||
rigctld.cpp \
|
||||
ring/ring.cpp
|
||||
ring/ring.cpp \
|
||||
transceiveradjustments.cpp \
|
||||
aboutbox.cpp
|
||||
|
||||
HEADERS += wfmain.h \
|
||||
commhandler.h \
|
||||
|
@ -157,14 +159,19 @@ HEADERS += wfmain.h \
|
|||
repeaterattributes.h \
|
||||
rigctld.h \
|
||||
ulaw.h \
|
||||
ring/ring.h
|
||||
ring/ring.h \
|
||||
transceiveradjustments.h \
|
||||
audiotaper.h \
|
||||
aboutbox.h
|
||||
|
||||
|
||||
FORMS += wfmain.ui \
|
||||
calibrationwindow.ui \
|
||||
satellitesetup.ui \
|
||||
udpserversetup.ui \
|
||||
repeatersetup.ui
|
||||
repeatersetup.ui \
|
||||
transceiveradjustments.ui \
|
||||
aboutbox.ui
|
||||
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue