Starting to add EME Echo mode. (Not yet functional!)

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5522 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2015-06-04 16:42:38 +00:00
parent aad2ec6950
commit 437c8c5c3f
12 changed files with 787 additions and 4 deletions

View File

@ -230,6 +230,8 @@ set (wsjtx_CXXSRCS
signalmeter.cpp
plotter.cpp
widegraph.cpp
echograph.cpp
echoplot.cpp
about.cpp
astro.cpp
messageaveraging.cpp
@ -394,6 +396,7 @@ set (wsjtx_UISRCS
mainwindow.ui
about.ui
astro.ui
echograph.ui
messageaveraging.ui
widegraph.ui
logqso.ui

View File

@ -13,6 +13,7 @@ namespace
"JT9W-1",
"JT4",
"WSPR",
"Echo",
};
}

View File

@ -20,6 +20,7 @@ public:
JT9W_1,
JT4,
WSPR,
Echo,
};
explicit Modes (QObject * parent = nullptr);

84
echograph.cpp Normal file
View File

@ -0,0 +1,84 @@
//#include "commons.h"
#include "echoplot.h"
#include "echograph.h"
#include "ui_echograph.h"
#define NSMAX2 1366
EchoGraph::EchoGraph(QWidget *parent) :
QDialog(parent),
ui(new Ui::EchoGraph)
{
ui->setupUi(this);
this->setWindowFlags(Qt::Dialog);
this->installEventFilter(parent); //Installing the filter
ui->echoPlot->setCursor(Qt::CrossCursor);
this->setMaximumWidth(2048);
this->setMaximumHeight(880);
ui->echoPlot->setMaximumHeight(800);
//Restore user's settings
QString inifile(QApplication::applicationDirPath());
inifile += "/emecho.ini";
QSettings settings(inifile, QSettings::IniFormat);
settings.beginGroup("EchoGraph");
ui->echoPlot->setPlotZero(settings.value("PlotZero", 0).toInt());
ui->echoPlot->setPlotGain(settings.value("PlotGain", 0).toInt());
ui->zeroSlider->setValue(ui->echoPlot->getPlotZero());
ui->gainSlider->setValue(ui->echoPlot->getPlotGain());
ui->smoothSpinBox->setValue(settings.value("Smooth",0).toInt());
ui->echoPlot->m_blue=settings.value("BlueCurve",false).toBool();
ui->cbBlue->setChecked(ui->echoPlot->m_blue);
settings.endGroup();
}
EchoGraph::~EchoGraph()
{
saveSettings();
delete ui;
}
void EchoGraph::saveSettings()
{
//Save user's settings
QString inifile(QApplication::applicationDirPath());
inifile += "/emecho.ini";
QSettings settings(inifile, QSettings::IniFormat);
settings.beginGroup("EchoGraph");
settings.setValue("PlotZero",ui->echoPlot->m_plotZero);
settings.setValue("PlotGain",ui->echoPlot->m_plotGain);
settings.setValue("Smooth",ui->echoPlot->m_smooth);
settings.setValue("BlueCurve",ui->echoPlot->m_blue);
settings.endGroup();
}
void EchoGraph::plotSpec()
{
ui->echoPlot->draw();
}
void EchoGraph::on_smoothSpinBox_valueChanged(int n)
{
ui->echoPlot->setSmooth(n);
ui->echoPlot->draw();
}
void EchoGraph::on_cbBlue_toggled(bool checked)
{
ui->echoPlot->m_blue=checked;
ui->echoPlot->draw();
}
void EchoGraph::on_gainSlider_valueChanged(int value)
{
ui->echoPlot->setPlotGain(value);
ui->echoPlot->draw();
}
void EchoGraph::on_zeroSlider_valueChanged(int value)
{
ui->echoPlot->setPlotZero(value);
ui->echoPlot->draw();
}

31
echograph.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef ECHOGRAPH_H
#define ECHOGRAPH_H
#include <QDialog>
namespace Ui {
class EchoGraph;
}
class EchoGraph : public QDialog
{
Q_OBJECT
public:
explicit EchoGraph(QWidget *parent = 0);
~EchoGraph();
void plotSpec();
void saveSettings();
private slots:
void on_smoothSpinBox_valueChanged(int n);
void on_cbBlue_toggled(bool checked);
void on_gainSlider_valueChanged(int value);
void on_zeroSlider_valueChanged(int value);
private:
Ui::EchoGraph *ui;
};
#endif // ECHOGRAPH_H

233
echograph.ui Normal file
View File

@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EchoGraph</class>
<widget class="QDialog" name="EchoGraph">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>625</width>
<height>336</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>570</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Echo Graph</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="EPlotter" name="echoPlot">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>273</width>
<height>200</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>6</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Gain</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="gainSlider">
<property name="minimum">
<number>-20</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Zero</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="zeroSlider">
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Smooth</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="smoothSpinBox">
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="cbBlue">
<property name="text">
<string>Blue</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>EPlotter</class>
<extends>QFrame</extends>
<header>plotter.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

292
echoplot.cpp Normal file
View File

@ -0,0 +1,292 @@
#include "echoplot.h"
//#include "commons.h"
#include <math.h>
#include <QDebug>
#include "moc_echoplot.cpp"
#define MAX_SCREENSIZE 2048
EPlotter::EPlotter(QWidget *parent) : //EPlotter Constructor
QFrame(parent)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setFocusPolicy(Qt::StrongFocus);
setAttribute(Qt::WA_PaintOnScreen,false);
setAutoFillBackground(false);
setAttribute(Qt::WA_OpaquePaintEvent, false);
setAttribute(Qt::WA_NoSystemBackground, true);
m_StartFreq = -200;
m_fftBinWidth=48000.0/131072.0;
m_fSpan=1000.0;
m_hdivs = HORZ_DIVS;
m_Running = false;
m_paintEventBusy=false;
m_2DPixmap = QPixmap(0,0);
m_ScalePixmap = QPixmap(0,0);
m_OverlayPixmap = QPixmap(0,0);
m_Size = QSize(0,0);
m_TxFreq = 1500;
m_line = 0;
m_dBStepSize=10;
m_Percent2DScreen = 89; //percent of screen used for 2D display
}
EPlotter::~EPlotter() { } // Destructor
QSize EPlotter::minimumSizeHint() const
{
return QSize(50, 50);
}
QSize EPlotter::sizeHint() const
{
return QSize(180, 180);
}
void EPlotter::resizeEvent(QResizeEvent* ) //resizeEvent()
{
if(!size().isValid()) return;
if( m_Size != size() ) { //if changed, resize pixmaps to new screensize
m_Size = size();
m_w = m_Size.width();
m_h = m_Size.height();
m_h1 = (100-m_Percent2DScreen)*(m_Size.height())/100;
m_h2 = (m_Percent2DScreen)*(m_Size.height())/100;
m_2DPixmap = QPixmap(m_Size.width(), m_h2);
m_2DPixmap.fill(Qt::black);
m_OverlayPixmap = QPixmap(m_Size.width(), m_h2);
m_OverlayPixmap.fill(Qt::black);
m_2DPixmap.fill(Qt::black);
m_ScalePixmap = QPixmap(m_w,30);
m_ScalePixmap.fill(Qt::white);
m_fSpan=m_w*m_fftBinWidth;
m_StartFreq=50 * int((-0.5*m_fSpan)/50.0 - 0.5);
}
DrawOverlay();
draw();
}
void EPlotter::paintEvent(QPaintEvent *) // paintEvent()
{
if(m_paintEventBusy) return;
m_paintEventBusy=true;
QPainter painter(this);
painter.drawPixmap(0,0,m_ScalePixmap);
painter.drawPixmap(0,m_h1,m_2DPixmap);
m_paintEventBusy=false;
}
void EPlotter::draw() //draw()
{
int i,j,y;
float blue[2000],red[2000];
float gain = pow(10.0,(m_plotGain/20.0));
if(m_2DPixmap.size().width()==0) return;
QPainter painter2D(&m_2DPixmap);
QRect tmp(0,0,m_w,m_h2);
painter2D.fillRect(tmp,Qt::black);
/*
if(datcom_.nclearave==0) {
QPoint LineBuf[MAX_SCREENSIZE];
QPen penBlue(QColor(0,255,255),1);
QPen penRed(Qt::red,1);
j=0;
int i0=1000 + int(m_StartFreq/m_fftBinWidth);
for(i=0; i<2000; i++) {
blue[i]=datcom_.blue[i];
red[i]=datcom_.red[i];
}
if(m_smooth>0) {
for(i=0; i<m_smooth; i++) {
int n2000=2000;
smo121_(blue,&n2000);
smo121_(red,&n2000);
}
}
if(m_blue) {
painter2D.setPen(penBlue);
j=0;
for(i=0; i<m_w; i++) {
y = 0.9*m_h2 - gain*(m_h/10.0)*(blue[i0+i]-1.0) - m_plotZero;
LineBuf[j].setX(i);
LineBuf[j].setY(y);
j++;
}
painter2D.drawPolyline(LineBuf,j);
}
painter2D.setPen(penRed);
j=0;
for(int i=0; i<m_w; i++) {
y = 0.9*m_h2 - gain*(m_h/10.0)*(red[i0+i]-1.0) - m_plotZero;
LineBuf[j].setX(i);
LineBuf[j].setY(y);
j++;
}
painter2D.drawPolyline(LineBuf,j);
}
*/
update(); //trigger a new paintEvent
}
void EPlotter::DrawOverlay() //DrawOverlay()
{
if(m_OverlayPixmap.isNull() or m_2DPixmap.isNull()) return;
// int w = m_WaterfallPixmap.width();
int x,y;
QRect rect;
QPainter painter(&m_OverlayPixmap);
painter.initFrom(this);
QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient
gradient.setColorAt(1, Qt::black);
gradient.setColorAt(0, Qt::darkBlue);
painter.setBrush(gradient);
painter.drawRect(0, 0, m_w, m_h2);
painter.setBrush(Qt::SolidPattern);
m_fSpan = m_w*m_fftBinWidth;
m_freqPerDiv=20;
if(m_fSpan>250) m_freqPerDiv=50;
float pixPerHdiv = m_freqPerDiv/m_fftBinWidth;
float pixPerVdiv = float(m_h2)/float(VERT_DIVS);
m_hdivs = m_w*m_fftBinWidth/m_freqPerDiv + 0.9999;
painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
for( int i=1; i<m_hdivs; i++) //draw vertical grids
{
x=int(i*pixPerHdiv);
painter.drawLine(x,0,x,m_h2);
}
for( int i=1; i<VERT_DIVS; i++) //draw horizontal grids
{
y = (int)( (float)i*pixPerVdiv );
painter.drawLine(0,y,m_w,y);
}
QRect rect0;
QPainter painter0(&m_ScalePixmap);
painter0.initFrom(this);
//create Font to use for scales
QFont Font("Arial");
Font.setPointSize(12);
QFontMetrics metrics(Font);
Font.setWeight(QFont::Normal);
painter0.setFont(Font);
painter0.setPen(Qt::black);
m_ScalePixmap.fill(Qt::white);
painter0.drawRect(0, 0, m_w, 30);
//draw tick marks on upper scale
for( int i=1; i<m_hdivs; i++) { //major ticks
x = (int)( (float)i*pixPerHdiv );
painter0.drawLine(x,18,x,30);
}
int minor=5;
if(m_freqPerDiv==200) minor=4;
for( int i=1; i<minor*m_hdivs; i++) { //minor ticks
x = i*pixPerHdiv/minor;
painter0.drawLine(x,24,x,30);
}
//draw frequency values
MakeFrequencyStrs();
for( int i=0; i<=m_hdivs; i++) {
if(0==i) {
//left justify the leftmost text
x = (int)( (float)i*pixPerHdiv);
rect0.setRect(x,0, (int)pixPerHdiv, 20);
painter0.drawText(rect0, Qt::AlignLeft|Qt::AlignVCenter,
m_HDivText[i]);
}
else if(m_hdivs == i) {
//right justify the rightmost text
x = (int)( (float)i*pixPerHdiv - pixPerHdiv);
rect0.setRect(x,0, (int)pixPerHdiv, 20);
painter0.drawText(rect0, Qt::AlignRight|Qt::AlignVCenter,
m_HDivText[i]);
} else {
//center justify the rest of the text
x = (int)( (float)i*pixPerHdiv - pixPerHdiv/2);
rect0.setRect(x,0, (int)pixPerHdiv, 20);
painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,
m_HDivText[i]);
}
}
QPen pen1(Qt::red, 3); //Mark Tx Freq with red tick
painter0.setPen(pen1);
x = XfromFreq(m_TxFreq);
painter0.drawLine(x,17,x,30);
}
void EPlotter::MakeFrequencyStrs() //MakeFrequencyStrs
{
float freq;
for(int i=0; i<=m_hdivs; i++) {
freq=m_StartFreq + i*m_freqPerDiv;
m_HDivText[i].setNum((int)freq);
}
}
int EPlotter::XfromFreq(float f) //XfromFreq()
{
int x = (int) m_w * (f - m_StartFreq)/m_fSpan;
if(x<0 ) return 0;
if(x>m_w) return m_w;
return x;
}
float EPlotter::FreqfromX(int x) //FreqfromX()
{
return float(m_StartFreq + x*m_fftBinWidth);
}
void EPlotter::SetRunningState(bool running) //SetRunningState()
{
m_Running = running;
}
void EPlotter::setPlotZero(int plotZero) //setPlotZero()
{
m_plotZero=plotZero;
}
int EPlotter::getPlotZero() //getPlotZero()
{
return m_plotZero;
}
void EPlotter::setPlotGain(int plotGain) //setPlotGain()
{
m_plotGain=plotGain;
}
int EPlotter::getPlotGain() //getPlotGain()
{
return m_plotGain;
}
void EPlotter::setSmooth(int n) //setSmooth()
{
m_smooth=n;
}
int EPlotter::getSmooth() //getSmooth()
{
return m_smooth;
}
int EPlotter::plotWidth(){return m_2DPixmap.width();}
void EPlotter::UpdateOverlay() {DrawOverlay();}

92
echoplot.h Normal file
View File

@ -0,0 +1,92 @@
///////////////////////////////////////////////////////////////////////////
// Some code in this file and accompanying files is based on work by
// Moe Wheatley, AE4Y, released under the "Simplified BSD License".
// For more details see the accompanying file LICENSE_WHEATLEY.TXT
///////////////////////////////////////////////////////////////////////////
#ifndef EPLOTTER_H
#define EPLOTTER_H
#include <QtWidgets>
#include <QFrame>
#include <QImage>
#include <cstring>
#define VERT_DIVS 7 //specify grid screen divisions
#define HORZ_DIVS 20
class EPlotter : public QFrame
{
Q_OBJECT
public:
explicit EPlotter(QWidget *parent = 0);
~EPlotter();
QSize minimumSizeHint() const;
QSize sizeHint() const;
QColor m_ColorTbl[256];
float m_fSpan;
qint32 m_TxFreq;
qint32 m_w;
qint32 m_plotZero;
qint32 m_plotGain;
qint32 m_smooth;
bool m_blue;
void draw(); //Update the waterfall
void SetRunningState(bool running);
void setPlotZero(int plotZero);
int getPlotZero();
void setPlotGain(int plotGain);
int getPlotGain();
int plotWidth();
void UpdateOverlay();
void DrawOverlay();
void setSmooth(int n);
int getSmooth();
// void SetPercent2DScreen(int percent){m_Percent2DScreen=percent;}
protected:
//re-implemented widget event handlers
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent* event);
private:
void MakeFrequencyStrs();
int XfromFreq(float f);
float FreqfromX(int x);
qint64 RoundFreq(qint64 freq, int resolution);
QPixmap m_2DPixmap;
QPixmap m_ScalePixmap;
QPixmap m_OverlayPixmap;
QSize m_Size;
QString m_Str;
QString m_HDivText[483];
double m_fftBinWidth;
qint64 m_StartFreq;
qint32 m_dBStepSize;
qint32 m_hdivs;
qint32 m_line;
qint32 m_freqPerDiv;
qint32 m_Percent2DScreen;
qint32 m_h;
qint32 m_h1;
qint32 m_h2;
bool m_Running;
bool m_paintEventBusy;
};
extern "C" {
//--------------------------------------------------- C and Fortran routines
void smo121_(float x[], int* npts);
}
#endif // EPLOTTER_H

View File

@ -20,6 +20,8 @@
#include "revision_utils.hpp"
#include "soundout.h"
#include "plotter.h"
#include "echoplot.h"
#include "echograph.h"
#include "about.h"
#include "astro.h"
#include "messageaveraging.h"
@ -72,6 +74,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
m_config {settings, this},
m_WSPR_band_hopping {settings, &m_config, this},
m_wideGraph (new WideGraph (settings)),
m_echoGraph (new EchoGraph),
m_logDlg (new LogQSO (program_title (), settings, this)),
m_dialFreq {std::numeric_limits<Radio::Frequency>::max ()},
m_detector (RX_SAMPLE_RATE, NTMAX, 6912 / 2, downSampleFactor),
@ -218,6 +221,7 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
ui->actionJT4->setActionGroup(modeGroup);
ui->actionWSPR_2->setActionGroup(modeGroup);
ui->actionWSPR_15->setActionGroup(modeGroup);
ui->actionEcho->setActionGroup(modeGroup);
QActionGroup* saveGroup = new QActionGroup(this);
ui->actionNone->setActionGroup(saveGroup);
@ -1276,6 +1280,11 @@ void MainWindow::on_actionWide_Waterfall_triggered() //Display Waterfalls
m_wideGraph->show();
}
void MainWindow::on_actionEcho_Graph_triggered()
{
m_echoGraph->show();
}
void MainWindow::on_actionAstronomical_data_triggered()
{
if (!m_astroWidget)
@ -3159,6 +3168,13 @@ void MainWindow::on_actionWSPR_15_triggered()
switch_mode (Modes::WSPR);
}
void MainWindow::on_actionEcho_triggered()
{
m_mode="Echo";
switch_mode(Modes::Echo);
if(!m_echoGraph->isVisible()) m_echoGraph->show();
}
void MainWindow::switch_mode (Mode mode)
{
auto f = m_dialFreq;
@ -4306,3 +4322,4 @@ void MainWindow::on_tabWidget_currentChanged (int new_value)
m_nonWSPRTab = new_value;
}
}

View File

@ -54,6 +54,7 @@ class QSettings;
class QLineEdit;
class QFont;
class QHostInfo;
class EchoGraph;
class WideGraph;
class LogQSO;
class Transceiver;
@ -230,6 +231,10 @@ private slots:
void on_pbTxNext_clicked(bool b);
void on_tabWidget_currentChanged (int);
void on_actionEcho_Graph_triggered();
void on_actionEcho_triggered();
private:
Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,
unsigned channels, unsigned msBuffered) const;
@ -266,6 +271,7 @@ private:
QMessageBox m_rigErrorMessageBox;
QScopedPointer<WideGraph> m_wideGraph;
QScopedPointer<EchoGraph> m_echoGraph;
QScopedPointer<LogQSO> m_logDlg;
QScopedPointer<Astro> m_astroWidget;
QScopedPointer<QTextEdit> m_shortcuts;

View File

@ -910,7 +910,7 @@
<string>Check to add 2.5 s to expected propagation delay.</string>
</property>
<property name="text">
<string>EME</string>
<string>EME delay</string>
</property>
</widget>
</item>
@ -2736,6 +2736,7 @@ QLabel[oob=&quot;true&quot;] {
<addaction name="actionWide_Waterfall"/>
<addaction name="actionAstronomical_data"/>
<addaction name="actionMessage_averaging"/>
<addaction name="actionEcho_Graph"/>
</widget>
<widget class="QMenu" name="menuDecode">
<property name="title">
@ -2779,6 +2780,7 @@ QLabel[oob=&quot;true&quot;] {
<addaction name="actionJT4"/>
<addaction name="actionWSPR_2"/>
<addaction name="actionWSPR_15"/>
<addaction name="actionEcho"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuView"/>
@ -3183,6 +3185,25 @@ QLabel[oob=&quot;true&quot;] {
<string>WSPR-15</string>
</property>
</action>
<action name="actionEcho_Graph">
<property name="text">
<string>Echo Graph</string>
</property>
<property name="shortcut">
<string>F8</string>
</property>
</action>
<action name="actionEcho">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Echo</string>
</property>
<property name="toolTip">
<string>EME Echo mode</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -91,7 +91,8 @@ SOURCES += \
main.cpp \
decodedtext.cpp \
wsprnet.cpp \
messageaveraging.cpp
messageaveraging.cpp \
echoplot.cpp echograph.cpp Modes.cpp
HEADERS += qt_helpers.hpp \
pimpl_h.hpp pimpl_impl.hpp \
@ -110,7 +111,8 @@ HEADERS += qt_helpers.hpp \
logbook/countrydat.h \
logbook/countriesworked.h \
logbook/adif.h \
messageaveraging.h
messageaveraging.h \
echoplot.h echograph.h Modes.hpp
INCLUDEPATH += qmake_only
@ -121,7 +123,7 @@ HEADERS += OmniRigTransceiver.hpp
FORMS += mainwindow.ui about.ui Configuration.ui widegraph.ui astro.ui \
logqso.ui wf_palette_design_dialog.ui \
messageaveraging.ui
messageaveraging.ui echograph.ui
RC_FILE = wsjtx.rc
RESOURCES = wsjtx.qrc