1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 01:55:48 -05:00

Spectrum Annotations. Implements #887

This commit is contained in:
f4exb 2022-01-21 00:18:41 +01:00
parent fbdbe13870
commit de8f64063f
24 changed files with 3614 additions and 1795 deletions

View File

@ -36,6 +36,7 @@ def getInputOptions():
parser.add_option("-j", "--json-file", dest="json_file", help="JSON file containing commands. Mandatory", metavar="FILE", type="string")
parser.add_option("-i", "--init", dest="initialize", help="Initialize instance before running script", action="store_true")
parser.add_option("-1", "--ignore-first-posts", dest="ignore_first_posts", help="Ignore first deviceset or featureset post in sequence", action="store_true")
parser.add_option("-d", "--delay", dest="delay_ms", help="force delay after each command (ms)", metavar="TIME", type="int")
(options, args) = parser.parse_args()
@ -134,6 +135,8 @@ def main():
delay = command.get('delay', None)
if delay is not None and isinstance(delay, int):
time.sleep(delay/1000)
elif options.delay_ms is not None:
time.sleep(options.delay_ms/1000)
print("All done!")

View File

@ -113,3 +113,51 @@ bool SpectrumWaterfallMarker::deserialize(const QByteArray& data)
return false;
}
}
QByteArray SpectrumAnnotationMarker::serialize() const
{
SimpleSerializer s(1);
s.writeS64(1, m_startFrequency);
s.writeU32(2, m_bandwidth);
int r, g, b;
m_markerColor.getRgb(&r, &g, &b);
s.writeS32(4, r);
s.writeS32(5, g);
s.writeS32(6, b);
s.writeBool(7, m_show);
s.writeString(8, m_text);
return s.final();
}
bool SpectrumAnnotationMarker::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if (!d.isValid()) {
return false;
}
if (d.getVersion() == 1)
{
d.readS64(1, &m_startFrequency, 0);
d.readU32(2, &m_bandwidth, 0);
int r, g, b;
d.readS32(4, &r, 255);
m_markerColor.setRed(r);
d.readS32(5, &g, 255);
m_markerColor.setGreen(g);
d.readS32(6, &b, 255);
m_markerColor.setBlue(b);
d.readBool(7, &m_show, true);
d.readString(8, &m_text);
return true;
}
else
{
return false;
}
}

View File

@ -155,4 +155,49 @@ struct SDRBASE_API SpectrumWaterfallMarker
bool deserialize(const QByteArray& data);
};
struct SDRBASE_API SpectrumAnnotationMarker
{
qint64 m_startFrequency;
uint32_t m_bandwidth;
QColor m_markerColor;
bool m_show;
QString m_text;
bool m_selected;
float m_startPos;
float m_stopPos;
SpectrumAnnotationMarker() :
m_startFrequency(0),
m_bandwidth(0),
m_markerColor("white"),
m_show(true),
m_text("Text"),
m_selected(false),
m_startPos(0.0f),
m_stopPos(1.0f)
{}
SpectrumAnnotationMarker(
qint64 startFrequency,
uint32_t bandwidth,
QColor markerColor,
bool show,
const QString& text
) :
m_startFrequency(startFrequency),
m_bandwidth(bandwidth),
m_markerColor(markerColor),
m_show(show),
m_text(text),
m_startPos(0.0f),
m_stopPos(1.0f)
{}
SpectrumAnnotationMarker(const SpectrumAnnotationMarker& other) = default;
SpectrumAnnotationMarker& operator=(const SpectrumAnnotationMarker&) = default;
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
};
#endif // INCLUDE_SPECTRUMMARKERS_H

View File

@ -15,6 +15,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QBuffer>
#include <QDataStream>
#include "SWGGLSpectrum.h"
#include "util/simpleserializer.h"
@ -102,9 +105,25 @@ QByteArray SpectrumSettings::serialize() const
s.writeBlob(111+i, m_waterfallMarkers[i].serialize());
}
QByteArray data;
QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly);
(*stream) << m_annoationMarkers;
delete stream;
s.writeBlob(40, data);
return s.final();
}
QDataStream& operator<<(QDataStream& out, const SpectrumAnnotationMarker& marker)
{
out << marker.m_startFrequency;
out << marker.m_bandwidth;
out << marker.m_markerColor;
out << marker.m_show;
out << marker.m_text;
return out;
}
bool SpectrumSettings::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
@ -182,6 +201,11 @@ bool SpectrumSettings::deserialize(const QByteArray& data)
m_waterfallMarkers.back().deserialize(bytetmp);
}
d.readBlob(40, &bytetmp);
QDataStream *stream = new QDataStream(bytetmp);
(*stream) >> m_annoationMarkers;
delete stream;
return true;
}
else
@ -191,6 +215,16 @@ bool SpectrumSettings::deserialize(const QByteArray& data)
}
}
QDataStream& operator>>(QDataStream& in, SpectrumAnnotationMarker& marker)
{
in >> marker.m_startFrequency;
in >> marker.m_bandwidth;
in >> marker.m_markerColor;
in >> marker.m_show;
in >> marker.m_text;
return in;
}
void SpectrumSettings::formatTo(SWGSDRangel::SWGObject *swgObject) const
{
SWGSDRangel::SWGGLSpectrum *swgSpectrum = static_cast<SWGSDRangel::SWGGLSpectrum *>(swgObject);
@ -256,6 +290,20 @@ void SpectrumSettings::formatTo(SWGSDRangel::SWGObject *swgObject) const
swgSpectrum->getWaterfallMarkers()->back()->setShow(marker.m_show ? 1 : 0);
}
}
if (m_annoationMarkers.size() > 0)
{
swgSpectrum->setAnnotationMarkers(new QList<SWGSDRangel::SWGSpectrumAnnotationMarker *>);
for (const auto &marker : m_annoationMarkers)
{
swgSpectrum->getAnnotationMarkers()->append(new SWGSDRangel::SWGSpectrumAnnotationMarker);
swgSpectrum->getAnnotationMarkers()->back()->setStartFrequency(marker.m_startFrequency);
swgSpectrum->getAnnotationMarkers()->back()->setBandwidth(marker.m_bandwidth);
swgSpectrum->getAnnotationMarkers()->back()->setMarkerColor(qColorToInt(marker.m_markerColor));
swgSpectrum->getAnnotationMarkers()->back()->setShow(marker.m_show ? 1 : 0);
}
}
}
void SpectrumSettings::updateFrom(const QStringList& keys, const SWGSDRangel::SWGObject *swgObject)
@ -351,6 +399,7 @@ void SpectrumSettings::updateFrom(const QStringList& keys, const SWGSDRangel::SW
{
QList<SWGSDRangel::SWGSpectrumHistogramMarker *> *swgHistogramMarkers = swgSpectrum->getHistogramMarkers();
m_histogramMarkers.clear();
int i = 0;
for (const auto &swgHistogramMarker : *swgHistogramMarkers)
{
@ -360,6 +409,10 @@ void SpectrumSettings::updateFrom(const QStringList& keys, const SWGSDRangel::SW
m_histogramMarkers.back().m_markerType = (SpectrumHistogramMarker::SpectrumMarkerType) swgHistogramMarker->getMarkerType();
m_histogramMarkers.back().m_markerColor = intToQColor(swgHistogramMarker->getMarkerColor());
m_histogramMarkers.back().m_show = swgHistogramMarker->getShow() != 0;
if (i++ == 10) { // no more than 10 markers
break;
}
}
}
@ -367,6 +420,7 @@ void SpectrumSettings::updateFrom(const QStringList& keys, const SWGSDRangel::SW
{
QList<SWGSDRangel::SWGSpectrumWaterfallMarker *> *swgWaterfallMarkers = swgSpectrum->getWaterfallMarkers();
m_waterfallMarkers.clear();
int i = 0;
for (const auto &swgWaterfallMarker : *swgWaterfallMarkers)
{
@ -375,6 +429,25 @@ void SpectrumSettings::updateFrom(const QStringList& keys, const SWGSDRangel::SW
m_waterfallMarkers.back().m_time = swgWaterfallMarker->getTime();
m_waterfallMarkers.back().m_markerColor = intToQColor(swgWaterfallMarker->getMarkerColor());
m_waterfallMarkers.back().m_show = swgWaterfallMarker->getShow() != 0;
if (i++ == 10) { // no more than 10 markers
break;
}
}
}
if (keys.contains("spectrumConfig.annotationMarkers"))
{
QList<SWGSDRangel::SWGSpectrumAnnotationMarker *> *swgAnnotationMarkers = swgSpectrum->getAnnotationMarkers();
m_waterfallMarkers.clear();
for (const auto &swgAnnotationMarker : *swgAnnotationMarkers)
{
m_annoationMarkers.push_back(SpectrumAnnotationMarker());
m_annoationMarkers.back().m_startFrequency = swgAnnotationMarker->getStartFrequency();
m_annoationMarkers.back().m_bandwidth = swgAnnotationMarker->getBandwidth() < 0 ? 0 : swgAnnotationMarker->getBandwidth();
m_annoationMarkers.back().m_markerColor = intToQColor(swgAnnotationMarker->getMarkerColor());
m_annoationMarkers.back().m_show = swgAnnotationMarker->getShow() != 0;
}
}
}

View File

@ -41,7 +41,8 @@ public:
enum MarkersDisplay
{
MarkersDisplayNone,
MarkersDisplaySpectrum
MarkersDisplaySpectrum,
MarkersDisplayAnnotations
};
int m_fftSize;
@ -73,6 +74,7 @@ public:
uint16_t m_wsSpectrumPort; //!< websocket spectrum server port
QList<SpectrumHistogramMarker> m_histogramMarkers;
QList<SpectrumWaterfallMarker> m_waterfallMarkers;
QList<SpectrumAnnotationMarker> m_annoationMarkers;
static const int m_log2FFTSizeMin = 6; // 64
static const int m_log2FFTSizeMax = 15; // 32k

View File

@ -6162,6 +6162,12 @@ margin-bottom: 20px;
"items" : {
"$ref" : "#/definitions/SpectrumWaterfallMarker"
}
},
"annotationMarkers" : {
"type" : "array",
"items" : {
"$ref" : "#/definitions/SpectrumAnnotationMarker"
}
}
},
"description" : "GLSpectrumGUI settings"
@ -11782,6 +11788,26 @@ margin-bottom: 20px;
}
},
"description" : "SoapySDR"
};
defs.SpectrumAnnotationMarker = {
"properties" : {
"startFrequency" : {
"type" : "integer",
"format" : "int64"
},
"bandwidth" : {
"type" : "integer"
},
"markerColor" : {
"type" : "integer",
"description" : "Color in 8 bit BGR serie"
},
"show" : {
"type" : "integer",
"description" : "Boolean - Marker display state\n * 0 - Hidden\n * 1 - Visible\n"
}
},
"description" : "Spectrum annotation marker settings"
};
defs.SpectrumHistogramMarker = {
"properties" : {
@ -11800,7 +11826,7 @@ margin-bottom: 20px;
},
"markerColor" : {
"type" : "integer",
"description" : "Color in 8 bit RGB serie"
"description" : "Color in 8 bit BGR serie"
},
"show" : {
"type" : "integer",
@ -11854,7 +11880,7 @@ margin-bottom: 20px;
},
"markerColor" : {
"type" : "integer",
"description" : "Color in 8 bit RGB serie"
"description" : "Color in 8 bit BGR serie"
},
"show" : {
"type" : "integer",
@ -51943,7 +51969,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2022-01-15T03:12:23.419+01:00
Generated 2022-01-15T23:01:29.100+01:00
</div>
</div>
</div>

View File

@ -17,7 +17,7 @@ SpectrumHistogramMarker:
* 2 - Max power
markerColor:
type: integer
description: Color in 8 bit RGB serie
description: Color in 8 bit BGR serie
show:
type: integer
description: >
@ -37,7 +37,25 @@ SpectrumWaterfallMarker:
description: Time shift in seconds
markerColor:
type: integer
description: Color in 8 bit RGB serie
description: Color in 8 bit BGR serie
show:
type: integer
description: >
Boolean - Marker display state
* 0 - Hidden
* 1 - Visible
SpectrumAnnotationMarker:
description: Spectrum annotation marker settings
properties:
startFrequency:
type: integer
format: int64
bandwidth:
type: integer
markerColor:
type: integer
description: Color in 8 bit BGR serie
show:
type: integer
description: >
@ -129,3 +147,7 @@ GLSpectrum:
type: array
items:
$ref: "/doc/swagger/include/GLSpectrum.yaml#/SpectrumWaterfallMarker"
annotationMarkers:
type: array
items:
$ref: "/doc/swagger/include/GLSpectrum.yaml#/SpectrumAnnotationMarker"

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@ class MessageQueue;
class SpectrumVis;
class SDRGUI_API GLSpectrum : public QGLWidget, public GLSpectrumInterface {
Q_OBJECT
Q_OBJECT
public:
class MsgReportSampleRate : public Message {
@ -110,43 +110,43 @@ public:
Real m_range;
};
GLSpectrum(QWidget* parent = nullptr);
virtual ~GLSpectrum();
GLSpectrum(QWidget* parent = nullptr);
virtual ~GLSpectrum();
void setCenterFrequency(qint64 frequency);
void setCenterFrequency(qint64 frequency);
qint64 getCenterFrequency() const { return m_centerFrequency; }
float getPowerMax() const;
float getTimeMax() const;
void setSampleRate(qint32 sampleRate);
void setTimingRate(qint32 timingRate);
void setSampleRate(qint32 sampleRate);
void setTimingRate(qint32 timingRate);
void setFFTOverlap(int overlap);
void setReferenceLevel(Real referenceLevel);
void setPowerRange(Real powerRange);
void setDecay(int decay);
void setDecayDivisor(int decayDivisor);
void setHistoStroke(int stroke);
void setDisplayWaterfall(bool display);
void setSsbSpectrum(bool ssbSpectrum);
void setLsbDisplay(bool lsbDisplay);
void setInvertedWaterfall(bool inv);
void setDisplayMaxHold(bool display);
void setDisplayCurrent(bool display);
void setDisplayHistogram(bool display);
void setDisplayGrid(bool display);
void setDisplayGridIntensity(int intensity);
void setDisplayTraceIntensity(int intensity);
void setLinear(bool linear);
qint32 getSampleRate() const { return m_sampleRate; }
void setReferenceLevel(Real referenceLevel);
void setPowerRange(Real powerRange);
void setDecay(int decay);
void setDecayDivisor(int decayDivisor);
void setHistoStroke(int stroke);
void setDisplayWaterfall(bool display);
void setSsbSpectrum(bool ssbSpectrum);
void setLsbDisplay(bool lsbDisplay);
void setInvertedWaterfall(bool inv);
void setDisplayMaxHold(bool display);
void setDisplayCurrent(bool display);
void setDisplayHistogram(bool display);
void setDisplayGrid(bool display);
void setDisplayGridIntensity(int intensity);
void setDisplayTraceIntensity(int intensity);
void setLinear(bool linear);
qint32 getSampleRate() const { return m_sampleRate; }
void addChannelMarker(ChannelMarker* channelMarker);
void removeChannelMarker(ChannelMarker* channelMarker);
void setMessageQueueToGUI(MessageQueue* messageQueue) { m_messageQueueToGUI = messageQueue; }
void addChannelMarker(ChannelMarker* channelMarker);
void removeChannelMarker(ChannelMarker* channelMarker);
void setMessageQueueToGUI(MessageQueue* messageQueue) { m_messageQueueToGUI = messageQueue; }
virtual void newSpectrum(const Real* spectrum, int nbBins, int fftSize);
void clearSpectrumHistogram();
virtual void newSpectrum(const Real* spectrum, int nbBins, int fftSize);
void clearSpectrumHistogram();
Real getWaterfallShare() const { return m_waterfallShare; }
void setWaterfallShare(Real waterfallShare);
Real getWaterfallShare() const { return m_waterfallShare; }
void setWaterfallShare(Real waterfallShare);
void setFPSPeriodMs(int fpsPeriodMs);
void setDisplayedStream(bool sourceOrSink, int streamIndex)
@ -161,72 +161,80 @@ public:
const QList<SpectrumWaterfallMarker>& getWaterfallMarkers() const { return m_waterfallMarkers; }
QList<SpectrumWaterfallMarker>& getWaterfallMarkers() { return m_waterfallMarkers; }
void setWaterfallMarkers(const QList<SpectrumWaterfallMarker>& waterfallMarkers);
const QList<SpectrumAnnotationMarker>& getAnnotationMarkers() const { return m_annotationMarkers; }
QList<SpectrumAnnotationMarker>& getAnnotationMarkers() { return m_annotationMarkers; }
void setAnnotationMarkers(const QList<SpectrumAnnotationMarker>& annotationMarkers);
void updateHistogramMarkers();
void updateWaterfallMarkers();
void updateAnnotationMarkers();
void updateMarkersDisplay();
SpectrumSettings::MarkersDisplay& getMarkersDisplay() { return m_markersDisplay; }
private:
struct ChannelMarkerState {
ChannelMarker* m_channelMarker;
QMatrix4x4 m_glMatrixWaterfall;
QMatrix4x4 m_glMatrixDsbWaterfall;
QMatrix4x4 m_glMatrixFreqScale;
QMatrix4x4 m_glMatrixDsbFreqScale;
QMatrix4x4 m_glMatrixHistogram;
QMatrix4x4 m_glMatrixDsbHistogram;
QRect m_rect;
struct ChannelMarkerState {
ChannelMarker* m_channelMarker;
QMatrix4x4 m_glMatrixWaterfall;
QMatrix4x4 m_glMatrixDsbWaterfall;
QMatrix4x4 m_glMatrixFreqScale;
QMatrix4x4 m_glMatrixDsbFreqScale;
QMatrix4x4 m_glMatrixHistogram;
QMatrix4x4 m_glMatrixDsbHistogram;
QRect m_rect;
ChannelMarkerState(ChannelMarker* channelMarker) :
m_channelMarker(channelMarker)
{ }
};
QList<ChannelMarkerState*> m_channelMarkerStates;
ChannelMarkerState(ChannelMarker* channelMarker) :
m_channelMarker(channelMarker)
{ }
};
QList<ChannelMarkerState*> m_channelMarkerStates;
enum CursorState {
CSNormal,
CSSplitter,
CSSplitterMoving,
CSChannel,
CSChannelMoving
};
enum CursorState {
CSNormal,
CSSplitter,
CSSplitterMoving,
CSChannel,
CSChannelMoving
};
QList<SpectrumHistogramMarker> m_histogramMarkers;
QList<SpectrumWaterfallMarker> m_waterfallMarkers;
QList<SpectrumAnnotationMarker> m_annotationMarkers;
QList<SpectrumAnnotationMarker*> m_sortedAnnotationMarkers;
QList<SpectrumAnnotationMarker*> m_visibleAnnotationMarkers;
SpectrumSettings::MarkersDisplay m_markersDisplay;
CursorState m_cursorState;
int m_cursorChannel;
CursorState m_cursorState;
int m_cursorChannel;
SpectrumVis* m_spectrumVis;
QTimer m_timer;
QTimer m_timer;
int m_fpsPeriodMs;
QMutex m_mutex;
bool m_mouseInside;
bool m_changesPending;
QMutex m_mutex;
bool m_mouseInside;
bool m_changesPending;
qint64 m_centerFrequency;
Real m_referenceLevel;
Real m_powerRange;
bool m_linear;
int m_decay;
quint32 m_sampleRate;
quint32 m_timingRate;
qint64 m_centerFrequency;
Real m_referenceLevel;
Real m_powerRange;
bool m_linear;
int m_decay;
quint32 m_sampleRate;
quint32 m_timingRate;
int m_fftOverlap;
int m_fftSize; //!< FFT size in number of bins
int m_fftSize; //!< FFT size in number of bins
int m_nbBins; //!< Number of visible FFT bins (zoom support)
bool m_displayGrid;
int m_displayGridIntensity;
int m_displayTraceIntensity;
bool m_invertedWaterfall;
bool m_displayGrid;
int m_displayGridIntensity;
int m_displayTraceIntensity;
bool m_invertedWaterfall;
std::vector<Real> m_maxHold;
bool m_displayMaxHold;
const Real *m_currentSpectrum;
bool m_displayCurrent;
std::vector<Real> m_maxHold;
bool m_displayMaxHold;
const Real *m_currentSpectrum;
bool m_displayCurrent;
Real m_waterfallShare;
Real m_waterfallShare;
int m_leftMargin;
int m_rightMargin;
@ -237,76 +245,78 @@ private:
int m_waterfallHeight;
int m_bottomMargin;
QFont m_textOverlayFont;
QPixmap m_leftMarginPixmap;
QPixmap m_frequencyPixmap;
QPixmap m_leftMarginPixmap;
QPixmap m_frequencyPixmap;
QPixmap m_infoPixmap;
ScaleEngine m_timeScale;
ScaleEngine m_powerScale;
ScaleEngine m_frequencyScale;
ScaleEngine m_timeScale;
ScaleEngine m_powerScale;
ScaleEngine m_frequencyScale;
QRectF m_histogramRect;
QRect m_frequencyScaleRect;
QRect m_frequencyScaleRect;
QRectF m_waterfallRect;
QRect m_infoRect;
QMatrix4x4 m_glFrequencyScaleBoxMatrix;
QMatrix4x4 m_glLeftScaleBoxMatrix;
QMatrix4x4 m_glFrequencyScaleBoxMatrix;
QMatrix4x4 m_glLeftScaleBoxMatrix;
QMatrix4x4 m_glInfoBoxMatrix;
QRgb m_waterfallPalette[240];
QImage* m_waterfallBuffer;
int m_waterfallBufferPos;
int m_waterfallTextureHeight;
int m_waterfallTexturePos;
QMatrix4x4 m_glWaterfallBoxMatrix;
bool m_displayWaterfall;
bool m_ssbSpectrum;
bool m_lsbDisplay;
QRgb m_waterfallPalette[240];
QImage* m_waterfallBuffer;
int m_waterfallBufferPos;
int m_waterfallTextureHeight;
int m_waterfallTexturePos;
QMatrix4x4 m_glWaterfallBoxMatrix;
bool m_displayWaterfall;
bool m_ssbSpectrum;
bool m_lsbDisplay;
QRgb m_histogramPalette[240];
QImage* m_histogramBuffer;
quint8* m_histogram; //!< Spectrum phosphor matrix of FFT width and PSD height scaled to 100. values [0..239]
int m_decayDivisor;
int m_decayDivisorCount;
int m_histogramStroke;
QMatrix4x4 m_glHistogramSpectrumMatrix;
QMatrix4x4 m_glHistogramBoxMatrix;
bool m_displayHistogram;
bool m_displayChanged;
QRgb m_histogramPalette[240];
QImage* m_histogramBuffer;
quint8* m_histogram; //!< Spectrum phosphor matrix of FFT width and PSD height scaled to 100. values [0..239]
int m_decayDivisor;
int m_decayDivisorCount;
int m_histogramStroke;
QMatrix4x4 m_glHistogramSpectrumMatrix;
QMatrix4x4 m_glHistogramBoxMatrix;
bool m_displayHistogram;
bool m_displayChanged;
bool m_displaySourceOrSink;
int m_displayStreamIndex;
float m_frequencyZoomFactor;
float m_frequencyZoomPos;
static const float m_maxFrequencyZoom;
static const float m_annotationMarkerHeight;
GLShaderSimple m_glShaderSimple;
GLShaderTextured m_glShaderLeftScale;
GLShaderTextured m_glShaderFrequencyScale;
GLShaderTextured m_glShaderWaterfall;
GLShaderTextured m_glShaderHistogram;
GLShaderSimple m_glShaderSimple;
GLShaderTextured m_glShaderLeftScale;
GLShaderTextured m_glShaderFrequencyScale;
GLShaderTextured m_glShaderWaterfall;
GLShaderTextured m_glShaderHistogram;
GLShaderTextured m_glShaderTextOverlay;
GLShaderTextured m_glShaderInfo;
int m_matrixLoc;
int m_colorLoc;
IncrementalArray<GLfloat> m_q3TickTime;
IncrementalArray<GLfloat> m_q3TickFrequency;
IncrementalArray<GLfloat> m_q3TickPower;
IncrementalArray<GLfloat> m_q3FFT;
int m_matrixLoc;
int m_colorLoc;
IncrementalArray<GLfloat> m_q3TickTime;
IncrementalArray<GLfloat> m_q3TickFrequency;
IncrementalArray<GLfloat> m_q3TickPower;
IncrementalArray<GLfloat> m_q3FFT;
MessageQueue *m_messageQueueToGUI;
MessageQueue *m_messageQueueToGUI;
void updateWaterfall(const Real *spectrum);
void updateHistogram(const Real *spectrum);
void updateWaterfall(const Real *spectrum);
void updateHistogram(const Real *spectrum);
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void drawSpectrumMarkers();
void drawAnnotationMarkers();
void stopDrag();
void applyChanges();
void stopDrag();
void applyChanges();
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void wheelEvent(QWheelEvent*);
void channelMarkerMove(QWheelEvent*, int mul);
void zoom(QWheelEvent*);
@ -319,8 +329,8 @@ private:
void setFrequencyScale();
void getFrequencyZoom(int64_t& centerFrequency, int& frequencySpan);
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
QString displayScaled(int64_t value, char type, int precision, bool showMult);
QString displayScaledF(float value, char type, int precision, bool showMult);
@ -335,12 +345,22 @@ private:
bool topHalf,
const QRectF& glRect);
void formatTextInfo(QString& info);
void updateSortedAnnotationMarkers();
static bool annotationDisplayLessThan(const SpectrumAnnotationMarker *m1, const SpectrumAnnotationMarker *m2)
{
if (m1->m_bandwidth == m2->m_bandwidth) {
return m1->m_startFrequency < m2->m_startFrequency;
} else {
return m1->m_bandwidth > m2->m_bandwidth; // larger bandwidths should come first for display (lower layer)
}
}
private slots:
void cleanup();
void tick();
void channelMarkerChanged();
void channelMarkerDestroyed(QObject* object);
void cleanup();
void tick();
void channelMarkerChanged();
void channelMarkerDestroyed(QObject* object);
};
#endif // INCLUDE_GLSPECTRUM_H

View File

@ -36,14 +36,14 @@
const int GLSpectrumGUI::m_fpsMs[] = {500, 200, 100, 50, 20, 10, 5};
GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
QWidget(parent),
ui(new Ui::GLSpectrumGUI),
m_spectrumVis(nullptr),
m_glSpectrum(nullptr),
QWidget(parent),
ui(new Ui::GLSpectrumGUI),
m_spectrumVis(nullptr),
m_glSpectrum(nullptr),
m_doApplySettings(true)
{
ui->setupUi(this);
on_linscale_toggled(false);
ui->setupUi(this);
on_linscale_toggled(false);
QString levelStyle = QString(
"QSpinBox {background-color: rgb(79, 79, 79);}"
@ -59,27 +59,27 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
// ui->levelRange->findChild<QLineEdit*>()->setStyleSheet("color: white; background-color: rgb(79, 79, 79); border: 1px solid gray; border-radius: 4px;");
// ui->levelRange->setStyleSheet("background-color: rgb(79, 79, 79);");
connect(&m_messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
connect(&m_messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
CRightClickEnabler *wsSpectrumRightClickEnabler = new CRightClickEnabler(ui->wsSpectrum);
connect(wsSpectrumRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openWebsocketSpectrumSettingsDialog(const QPoint &)));
displaySettings();
setAveragingCombo();
setAveragingCombo();
applySettings();
}
GLSpectrumGUI::~GLSpectrumGUI()
{
delete ui;
delete ui;
}
void GLSpectrumGUI::setBuddies(SpectrumVis* spectrumVis, GLSpectrum* glSpectrum)
{
m_spectrumVis = spectrumVis;
m_glSpectrum = glSpectrum;
m_spectrumVis = spectrumVis;
m_glSpectrum = glSpectrum;
m_glSpectrum->setSpectrumVis(spectrumVis);
m_glSpectrum->setMessageQueueToGUI(&m_messageQueue);
m_glSpectrum->setMessageQueueToGUI(&m_messageQueue);
m_spectrumVis->setMessageQueueToGUI(&m_messageQueue);
}
@ -87,7 +87,7 @@ void GLSpectrumGUI::resetToDefaults()
{
m_settings.resetToDefaults();
displaySettings();
applySettings();
applySettings();
}
QByteArray GLSpectrumGUI::serialize() const
@ -134,40 +134,40 @@ void GLSpectrumGUI::updateSettings()
void GLSpectrumGUI::displaySettings()
{
blockApplySettings(true);
ui->refLevel->setValue(m_settings.m_refLevel);
ui->levelRange->setValue(m_settings.m_powerRange);
ui->decay->setSliderPosition(m_settings.m_decay);
ui->decayDivisor->setSliderPosition(m_settings.m_decayDivisor);
ui->stroke->setSliderPosition(m_settings.m_histogramStroke);
ui->waterfall->setChecked(m_settings.m_displayWaterfall);
ui->maxHold->setChecked(m_settings.m_displayMaxHold);
ui->current->setChecked(m_settings.m_displayCurrent);
ui->histogram->setChecked(m_settings.m_displayHistogram);
ui->invertWaterfall->setChecked(m_settings.m_invertedWaterfall);
ui->grid->setChecked(m_settings.m_displayGrid);
ui->gridIntensity->setSliderPosition(m_settings.m_displayGridIntensity);
ui->refLevel->setValue(m_settings.m_refLevel);
ui->levelRange->setValue(m_settings.m_powerRange);
ui->decay->setSliderPosition(m_settings.m_decay);
ui->decayDivisor->setSliderPosition(m_settings.m_decayDivisor);
ui->stroke->setSliderPosition(m_settings.m_histogramStroke);
ui->waterfall->setChecked(m_settings.m_displayWaterfall);
ui->maxHold->setChecked(m_settings.m_displayMaxHold);
ui->current->setChecked(m_settings.m_displayCurrent);
ui->histogram->setChecked(m_settings.m_displayHistogram);
ui->invertWaterfall->setChecked(m_settings.m_invertedWaterfall);
ui->grid->setChecked(m_settings.m_displayGrid);
ui->gridIntensity->setSliderPosition(m_settings.m_displayGridIntensity);
ui->decay->setToolTip(QString("Decay: %1").arg(m_settings.m_decay));
ui->decayDivisor->setToolTip(QString("Decay divisor: %1").arg(m_settings.m_decayDivisor));
ui->stroke->setToolTip(QString("Stroke: %1").arg(m_settings.m_histogramStroke));
ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(m_settings.m_displayGridIntensity));
ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(m_settings.m_displayTraceIntensity));
ui->decay->setToolTip(QString("Decay: %1").arg(m_settings.m_decay));
ui->decayDivisor->setToolTip(QString("Decay divisor: %1").arg(m_settings.m_decayDivisor));
ui->stroke->setToolTip(QString("Stroke: %1").arg(m_settings.m_histogramStroke));
ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(m_settings.m_displayGridIntensity));
ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(m_settings.m_displayTraceIntensity));
ui->fftWindow->blockSignals(true);
ui->averaging->blockSignals(true);
ui->averagingMode->blockSignals(true);
ui->linscale->blockSignals(true);
ui->fftWindow->blockSignals(true);
ui->averaging->blockSignals(true);
ui->averagingMode->blockSignals(true);
ui->linscale->blockSignals(true);
ui->fftWindow->setCurrentIndex(m_settings.m_fftWindow);
ui->fftWindow->setCurrentIndex(m_settings.m_fftWindow);
for (int i = SpectrumSettings::m_log2FFTSizeMin; i <= SpectrumSettings::m_log2FFTSizeMax; i++)
{
if (m_settings.m_fftSize == (1 << i))
{
ui->fftSize->setCurrentIndex(i - SpectrumSettings::m_log2FFTSizeMin);
break;
}
}
for (int i = SpectrumSettings::m_log2FFTSizeMin; i <= SpectrumSettings::m_log2FFTSizeMax; i++)
{
if (m_settings.m_fftSize == (1 << i))
{
ui->fftSize->setCurrentIndex(i - SpectrumSettings::m_log2FFTSizeMin);
break;
}
}
setFFTSizeToolitp();
unsigned int i = 0;
@ -183,15 +183,15 @@ void GLSpectrumGUI::displaySettings()
ui->fftOverlap->setValue(m_settings.m_fftOverlap);
setMaximumOverlap();
ui->averaging->setCurrentIndex(m_settings.m_averagingIndex);
ui->averagingMode->setCurrentIndex((int) m_settings.m_averagingMode);
ui->linscale->setChecked(m_settings.m_linear);
setAveragingToolitp();
ui->averaging->setCurrentIndex(m_settings.m_averagingIndex);
ui->averagingMode->setCurrentIndex((int) m_settings.m_averagingMode);
ui->linscale->setChecked(m_settings.m_linear);
setAveragingToolitp();
ui->fftWindow->blockSignals(false);
ui->averaging->blockSignals(false);
ui->averagingMode->blockSignals(false);
ui->linscale->blockSignals(false);
ui->fftWindow->blockSignals(false);
ui->averaging->blockSignals(false);
ui->averagingMode->blockSignals(false);
ui->linscale->blockSignals(false);
blockApplySettings(false);
}
@ -250,23 +250,24 @@ void GLSpectrumGUI::applySpectrumSettings()
m_glSpectrum->setHistogramMarkers(m_settings.m_histogramMarkers);
m_glSpectrum->setWaterfallMarkers(m_settings.m_waterfallMarkers);
m_glSpectrum->setAnnotationMarkers(m_settings.m_annoationMarkers);
}
void GLSpectrumGUI::on_fftWindow_currentIndexChanged(int index)
{
qDebug("GLSpectrumGUI::on_fftWindow_currentIndexChanged: %d", index);
m_settings.m_fftWindow = (FFTWindow::Function) index;
applySettings();
qDebug("GLSpectrumGUI::on_fftWindow_currentIndexChanged: %d", index);
m_settings.m_fftWindow = (FFTWindow::Function) index;
applySettings();
}
void GLSpectrumGUI::on_fftSize_currentIndexChanged(int index)
{
qDebug("GLSpectrumGUI::on_fftSize_currentIndexChanged: %d", index);
m_settings.m_fftSize = 1 << (SpectrumSettings::m_log2FFTSizeMin + index);
qDebug("GLSpectrumGUI::on_fftSize_currentIndexChanged: %d", index);
m_settings.m_fftSize = 1 << (SpectrumSettings::m_log2FFTSizeMin + index);
setAveragingCombo();
setMaximumOverlap();
applySettings();
setAveragingToolitp();
applySettings();
setAveragingToolitp();
setFFTSizeToolitp();
}
@ -309,8 +310,8 @@ void GLSpectrumGUI::on_autoscale_clicked(bool checked)
m_settings.m_refLevel = maxLvl;
m_settings.m_powerRange = maxLvl - minLvl;
ui->refLevel->setValue(m_settings.m_refLevel);
ui->levelRange->setValue(m_settings.m_powerRange);
ui->refLevel->setValue(m_settings.m_refLevel);
ui->levelRange->setValue(m_settings.m_powerRange);
// qDebug("GLSpectrumGUI::on_autoscale_clicked: max: %d min %d max: %e min: %e",
// maxLvl, minLvl, maxAvg, minAvg);
@ -319,7 +320,7 @@ void GLSpectrumGUI::on_autoscale_clicked(bool checked)
void GLSpectrumGUI::on_averagingMode_currentIndexChanged(int index)
{
qDebug("GLSpectrumGUI::on_averagingMode_currentIndexChanged: %d", index);
qDebug("GLSpectrumGUI::on_averagingMode_currentIndexChanged: %d", index);
m_settings.m_averagingMode = index < 0 ?
SpectrumSettings::AvgModeNone :
index > 3 ?
@ -327,23 +328,23 @@ void GLSpectrumGUI::on_averagingMode_currentIndexChanged(int index)
(SpectrumSettings::AveragingMode) index;
setAveragingCombo();
applySettings();
applySettings();
setAveragingToolitp();
}
void GLSpectrumGUI::on_averaging_currentIndexChanged(int index)
{
qDebug("GLSpectrumGUI::on_averaging_currentIndexChanged: %d", index);
qDebug("GLSpectrumGUI::on_averaging_currentIndexChanged: %d", index);
m_settings.m_averagingIndex = index;
applySettings();
applySettings();
setAveragingToolitp();
}
void GLSpectrumGUI::on_linscale_toggled(bool checked)
{
qDebug("GLSpectrumGUI::on_averaging_currentIndexChanged: %s", checked ? "lin" : "log");
qDebug("GLSpectrumGUI::on_averaging_currentIndexChanged: %s", checked ? "lin" : "log");
m_settings.m_linear = checked;
applySettings();
applySettings();
}
void GLSpectrumGUI::on_wsSpectrum_toggled(bool checked)
@ -366,6 +367,7 @@ void GLSpectrumGUI::on_markers_clicked(bool checked)
SpectrumMarkersDialog markersDialog(
m_glSpectrum->getHistogramMarkers(),
m_glSpectrum->getWaterfallMarkers(),
m_glSpectrum->getAnnotationMarkers(),
m_glSpectrum->getMarkersDisplay(),
this
);
@ -376,24 +378,27 @@ void GLSpectrumGUI::on_markers_clicked(bool checked)
connect(&markersDialog, SIGNAL(updateHistogram()), this, SLOT(updateHistogramMarkers()));
connect(&markersDialog, SIGNAL(updateWaterfall()), this, SLOT(updateWaterfallMarkers()));
connect(&markersDialog, SIGNAL(updateAnnotations()), this, SLOT(updateAnnotationMarkers()));
connect(&markersDialog, SIGNAL(updateMarkersDisplay()), this, SLOT(updateMarkersDisplay()));
markersDialog.exec();
m_settings.m_histogramMarkers = m_glSpectrum->getHistogramMarkers();
m_settings.m_waterfallMarkers = m_glSpectrum->getWaterfallMarkers();
m_settings.m_annoationMarkers = m_glSpectrum->getAnnotationMarkers();
applySettings();
}
void GLSpectrumGUI::on_refLevel_valueChanged(int value)
{
m_settings.m_refLevel = value;
m_settings.m_refLevel = value;
applySettings();
}
void GLSpectrumGUI::on_levelRange_valueChanged(int value)
{
m_settings.m_powerRange = value;
m_settings.m_powerRange = value;
applySettings();
}
@ -406,72 +411,72 @@ void GLSpectrumGUI::on_fps_currentIndexChanged(int index)
void GLSpectrumGUI::on_decay_valueChanged(int index)
{
m_settings.m_decay = index;
ui->decay->setToolTip(QString("Decay: %1").arg(m_settings.m_decay));
m_settings.m_decay = index;
ui->decay->setToolTip(QString("Decay: %1").arg(m_settings.m_decay));
applySettings();
}
void GLSpectrumGUI::on_decayDivisor_valueChanged(int index)
{
m_settings.m_decayDivisor = index;
ui->decayDivisor->setToolTip(QString("Decay divisor: %1").arg(m_settings.m_decayDivisor));
m_settings.m_decayDivisor = index;
ui->decayDivisor->setToolTip(QString("Decay divisor: %1").arg(m_settings.m_decayDivisor));
applySettings();
}
void GLSpectrumGUI::on_stroke_valueChanged(int index)
{
m_settings.m_histogramStroke = index;
ui->stroke->setToolTip(QString("Stroke: %1").arg(m_settings.m_histogramStroke));
m_settings.m_histogramStroke = index;
ui->stroke->setToolTip(QString("Stroke: %1").arg(m_settings.m_histogramStroke));
applySettings();
}
void GLSpectrumGUI::on_waterfall_toggled(bool checked)
{
m_settings.m_displayWaterfall = checked;
m_settings.m_displayWaterfall = checked;
applySettings();
}
void GLSpectrumGUI::on_histogram_toggled(bool checked)
{
m_settings.m_displayHistogram = checked;
m_settings.m_displayHistogram = checked;
applySettings();
}
void GLSpectrumGUI::on_maxHold_toggled(bool checked)
{
m_settings.m_displayMaxHold = checked;
m_settings.m_displayMaxHold = checked;
applySettings();
}
void GLSpectrumGUI::on_current_toggled(bool checked)
{
m_settings.m_displayCurrent = checked;
m_settings.m_displayCurrent = checked;
applySettings();
}
void GLSpectrumGUI::on_invertWaterfall_toggled(bool checked)
{
m_settings.m_invertedWaterfall = checked;
m_settings.m_invertedWaterfall = checked;
applySettings();
}
void GLSpectrumGUI::on_grid_toggled(bool checked)
{
m_settings.m_displayGrid = checked;
m_settings.m_displayGrid = checked;
applySettings();
}
void GLSpectrumGUI::on_gridIntensity_valueChanged(int index)
{
m_settings.m_displayGridIntensity = index;
ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(m_settings.m_displayGridIntensity));
m_settings.m_displayGridIntensity = index;
ui->gridIntensity->setToolTip(QString("Grid intensity: %1").arg(m_settings.m_displayGridIntensity));
applySettings();
}
void GLSpectrumGUI::on_traceIntensity_valueChanged(int index)
{
m_settings.m_displayTraceIntensity = index;
ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(m_settings.m_displayTraceIntensity));
m_settings.m_displayTraceIntensity = index;
ui->traceIntensity->setToolTip(QString("Trace intensity: %1").arg(m_settings.m_displayTraceIntensity));
applySettings();
}
@ -479,9 +484,9 @@ void GLSpectrumGUI::on_clearSpectrum_clicked(bool checked)
{
(void) checked;
if (m_glSpectrum) {
m_glSpectrum->clearSpectrumHistogram();
}
if (m_glSpectrum) {
m_glSpectrum->clearSpectrumHistogram();
}
}
void GLSpectrumGUI::on_freeze_toggled(bool checked)
@ -493,7 +498,7 @@ void GLSpectrumGUI::on_freeze_toggled(bool checked)
void GLSpectrumGUI::setAveragingCombo()
{
int index = ui->averaging->currentIndex();
ui->averaging->blockSignals(true);
ui->averaging->blockSignals(true);
ui->averaging->clear();
ui->averaging->addItem(QString("1"));
uint64_t maxAveraging = SpectrumSettings::getMaxAveragingValue(m_settings.m_fftSize, m_settings.m_averagingMode);
@ -523,7 +528,7 @@ void GLSpectrumGUI::setAveragingCombo()
}
ui->averaging->setCurrentIndex(index >= ui->averaging->count() ? ui->averaging->count() - 1 : index);
ui->averaging->blockSignals(false);
ui->averaging->blockSignals(false);
}
void GLSpectrumGUI::setNumberStr(int n, QString& s)
@ -732,3 +737,17 @@ void GLSpectrumGUI::updateWaterfallMarkers()
m_glSpectrum->updateWaterfallMarkers();
}
}
void GLSpectrumGUI::updateAnnotationMarkers()
{
if (m_glSpectrum) {
m_glSpectrum->updateAnnotationMarkers();
}
}
void GLSpectrumGUI::updateMarkersDisplay()
{
if (m_glSpectrum) {
m_glSpectrum->updateMarkersDisplay();
}
}

View File

@ -117,6 +117,8 @@ private slots:
void updateHistogramMarkers();
void updateWaterfallMarkers();
void updateAnnotationMarkers();
void updateMarkersDisplay();
};
#endif // INCLUDE_GLSPECTRUMGUI_H

View File

@ -17,8 +17,10 @@
///////////////////////////////////////////////////////////////////////////////////
#include <QColorDialog>
#include <QFileDialog>
#include "util/db.h"
#include "util/csv.h"
#include "spectrummarkersdialog.h"
#include "ui_spectrummarkersdialog.h"
@ -27,17 +29,21 @@
SpectrumMarkersDialog::SpectrumMarkersDialog(
QList<SpectrumHistogramMarker>& histogramMarkers,
QList<SpectrumWaterfallMarker>& waterfallMarkers,
QList<SpectrumAnnotationMarker>& annotationMarkers,
SpectrumSettings::MarkersDisplay& markersDisplay,
QWidget* parent) :
QDialog(parent),
ui(new Ui::SpectrumMarkersDialog),
m_histogramMarkers(histogramMarkers),
m_waterfallMarkers(waterfallMarkers),
m_annotationMarkers(annotationMarkers),
m_markersDisplay(markersDisplay),
m_histogramMarkerIndex(0),
m_waterfallMarkerIndex(0),
m_annotationMarkerIndex(0),
m_centerFrequency(0),
m_power(0.5f)
m_power(0.5f),
m_annoFreqStartElseCenter(true)
{
ui->setupUi(this);
ui->markerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
@ -46,9 +52,15 @@ SpectrumMarkersDialog::SpectrumMarkersDialog(
ui->wMarkerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->wMarkerFrequency->setValueRange(false, 10, -9999999999L, 9999999999L);
ui->wMarker->setMaximum(m_waterfallMarkers.size() - 1);
ui->aMarkerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->aMarkerFrequency->setValueRange(false, 10, -9999999999L, 9999999999L);
ui->aMarker->setMaximum(m_annotationMarkers.size() - 1);
ui->aMarkerBandwidth->setColorMapper(ColorMapper::GrayYellow);
ui->aMarkerBandwidth->setValueRange(true, 9, 0, 999999999L);
ui->showSelect->setCurrentIndex((int) m_markersDisplay);
displayHistogramMarker();
displayWaterfallMarker();
displayAnnotationMarker();
}
SpectrumMarkersDialog::~SpectrumMarkersDialog()
@ -56,6 +68,14 @@ SpectrumMarkersDialog::~SpectrumMarkersDialog()
void SpectrumMarkersDialog::displayHistogramMarker()
{
ui->markerFrequency->blockSignals(true);
ui->centerFrequency->blockSignals(true);
ui->markerColor->blockSignals(true);
ui->showMarker->blockSignals(true);
ui->marker->blockSignals(true);
ui->powerMode->blockSignals(true);
ui->fixedPower->blockSignals(true);
if (m_histogramMarkers.size() == 0)
{
ui->marker->setEnabled(false);
@ -63,6 +83,7 @@ void SpectrumMarkersDialog::displayHistogramMarker()
ui->powerMode->setEnabled(false);
ui->fixedPower->setEnabled(false);
ui->showMarker->setEnabled(false);
ui->marker->setValue(0);
ui->markerText->setText("-");
ui->fixedPower->setValue(0);
ui->fixedPowerText->setText(tr("0.0"));
@ -74,6 +95,7 @@ void SpectrumMarkersDialog::displayHistogramMarker()
ui->powerMode->setEnabled(true);
ui->fixedPower->setEnabled(true);
ui->showMarker->setEnabled(true);
ui->marker->setValue(m_histogramMarkerIndex);
ui->markerText->setText(tr("%1").arg(m_histogramMarkerIndex));
ui->markerFrequency->setValue(m_histogramMarkers[m_histogramMarkerIndex].m_frequency);
ui->powerMode->setCurrentIndex((int) m_histogramMarkers[m_histogramMarkerIndex].m_markerType);
@ -85,10 +107,27 @@ void SpectrumMarkersDialog::displayHistogramMarker()
ui->markerColor->setStyleSheet(tr("QLabel { background-color : rgb(%1,%2,%3); }").arg(r).arg(g).arg(b));
ui->showMarker->setChecked(m_histogramMarkers[m_histogramMarkerIndex].m_show);
}
ui->markerFrequency->blockSignals(false);
ui->centerFrequency->blockSignals(false);
ui->markerColor->blockSignals(false);
ui->showMarker->blockSignals(false);
ui->marker->blockSignals(false);
ui->powerMode->blockSignals(false);
ui->fixedPower->blockSignals(false);
}
void SpectrumMarkersDialog::displayWaterfallMarker()
{
ui->wMarkerFrequency->blockSignals(true);
ui->wCenterFrequency->blockSignals(true);
ui->wMarkerColor->blockSignals(true);
ui->wShowMarker->blockSignals(true);
ui->wMarker->blockSignals(true);
ui->timeFine->blockSignals(true);
ui->timeCoarse->blockSignals(true);
ui->timeExp->blockSignals(true);
if (m_waterfallMarkers.size() == 0)
{
ui->wMarker->setEnabled(false);
@ -97,6 +136,7 @@ void SpectrumMarkersDialog::displayWaterfallMarker()
ui->timeFine->setEnabled(false);
ui->timeExp->setEnabled(false);
ui->wShowMarker->setEnabled(false);
ui->wMarker->setValue(0);
ui->wMarkerText->setText("-");
ui->timeCoarse->setValue(0);
ui->timeFine->setValue(0);
@ -112,6 +152,7 @@ void SpectrumMarkersDialog::displayWaterfallMarker()
ui->timeFine->setEnabled(true);
ui->timeExp->setEnabled(true);
ui->wShowMarker->setEnabled(true);
ui->wMarker->setValue(m_waterfallMarkerIndex);
ui->wMarkerText->setText(tr("%1").arg(m_waterfallMarkerIndex));
ui->wMarkerFrequency->setValue(m_waterfallMarkers[m_waterfallMarkerIndex].m_frequency);
int r,g,b,a;
@ -119,6 +160,75 @@ void SpectrumMarkersDialog::displayWaterfallMarker()
ui->wMarkerColor->setStyleSheet(tr("QLabel { background-color : rgb(%1,%2,%3); }").arg(r).arg(g).arg(b));
displayTime(m_waterfallMarkers[m_waterfallMarkerIndex].m_time);
}
ui->wMarkerFrequency->blockSignals(false);
ui->wCenterFrequency->blockSignals(false);
ui->wMarkerColor->blockSignals(false);
ui->wShowMarker->blockSignals(false);
ui->wMarker->blockSignals(false);
ui->timeFine->blockSignals(false);
ui->timeCoarse->blockSignals(false);
ui->timeExp->blockSignals(false);
}
void SpectrumMarkersDialog::displayAnnotationMarker()
{
ui->aMarkerFrequency->blockSignals(true);
ui->aCenterFrequency->blockSignals(true);
ui->aMarkerColor->blockSignals(true);
ui->aShowMarker->blockSignals(true);
ui->aMarkerText->blockSignals(true);
ui->aMarker->blockSignals(true);
ui->aMarkerAdd->blockSignals(true);
ui->aMarkerDel->blockSignals(true);
ui->aMarkerBandwidth->blockSignals(true);
ui->aMarkerToggleFrequency->blockSignals(true);
if (m_annotationMarkers.size() == 0)
{
ui->aMarker->setEnabled(false);
ui->aMarkerFrequency->setEnabled(false);
ui->aMarkerBandwidth->setEnabled(false);
ui->aShowMarker->setEnabled(false);
ui->aMarkerIndexText->setText("-");
ui->aMarkerText->setText("");
}
else
{
ui->aMarker->setEnabled(true);
ui->aMarkerFrequency->setEnabled(true);
ui->aMarkerBandwidth->setEnabled(true);
ui->aShowMarker->setEnabled(true);
ui->aMarker->setValue(m_annotationMarkerIndex);
ui->aMarkerIndexText->setText(tr("%1").arg(m_annotationMarkerIndex));
qint64 frequency = m_annotationMarkers[m_annotationMarkerIndex].m_startFrequency +
(m_annoFreqStartElseCenter ? 0 : m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth / 2);
ui->aMarkerFrequency->setValue(frequency);
ui->aMarkerBandwidth->setValue(m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth);
ui->aMarkerFreqLabel->setText(m_annoFreqStartElseCenter ? "Cent" : "Start");
frequency = m_annotationMarkers[m_annotationMarkerIndex].m_startFrequency +
(m_annoFreqStartElseCenter ? m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth / 2 : 0);
ui->aMarkerFreqText->setText(tr("%L1").arg(frequency));
ui->aMarkerStopText->setText(tr("%L1").arg(
m_annotationMarkers[m_annotationMarkerIndex].m_startFrequency + m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth));
int r,g,b,a;
m_annotationMarkers[m_annotationMarkerIndex].m_markerColor.getRgb(&r, &g, &b, &a);
ui->aMarkerColor->setStyleSheet(tr("QLabel { background-color : rgb(%1,%2,%3); }").arg(r).arg(g).arg(b));
ui->aMarkerText->setText(tr("%1").arg(m_annotationMarkers[m_annotationMarkerIndex].m_text));
}
ui->aMarkerToggleFrequency->setChecked(m_annoFreqStartElseCenter);
ui->aMarkerFrequency->blockSignals(false);
ui->aCenterFrequency->blockSignals(false);
ui->aMarkerColor->blockSignals(false);
ui->aShowMarker->blockSignals(false);
ui->aMarkerText->blockSignals(false);
ui->aMarker->blockSignals(false);
ui->aMarkerAdd->blockSignals(false);
ui->aMarkerDel->blockSignals(false);
ui->aMarkerBandwidth->blockSignals(false);
ui->aMarkerToggleFrequency->blockSignals(false);
}
void SpectrumMarkersDialog::displayTime(float time)
@ -426,7 +536,252 @@ void SpectrumMarkersDialog::on_wMarkerDel_clicked()
displayWaterfallMarker();
}
void SpectrumMarkersDialog::on_aMarkerToggleFrequency_toggled(bool checked)
{
m_annoFreqStartElseCenter = checked;
ui->aMarkerToggleFrequency->setText(checked ? "Start" : "Cent");
displayAnnotationMarker();
}
void SpectrumMarkersDialog::on_aMarkerFrequency_changed(qint64 value)
{
if (m_annotationMarkers.size() == 0) {
return;
}
if (m_annoFreqStartElseCenter) {
m_annotationMarkers[m_annotationMarkerIndex].m_startFrequency = value;
} else {
m_annotationMarkers[m_annotationMarkerIndex].m_startFrequency = value -
(m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth / 2);
}
displayAnnotationMarker();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aCenterFrequency_clicked()
{
if (m_annotationMarkers.size() == 0) {
return;
}
qDebug("SpectrumMarkersDialog::on_aCenterFrequency_clicked: %lld", m_centerFrequency);
m_annotationMarkers[m_annotationMarkerIndex].m_startFrequency = m_centerFrequency -
(m_annoFreqStartElseCenter ? 0 : m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth/2);
displayAnnotationMarker();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aMakerDuplicate_clicked()
{
if (m_annotationMarkers.size() == 0) {
return;
}
m_annotationMarkers.push_back(m_annotationMarkers[m_annotationMarkerIndex]);
ui->aMarker->setMaximum(m_annotationMarkers.size() - 1);
m_annotationMarkerIndex = m_annotationMarkers.size() - 1;
displayAnnotationMarker();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aMakersSort_clicked()
{
std::sort(m_annotationMarkers.begin(), m_annotationMarkers.end(), annotationMarkerLessThan);
displayAnnotationMarker();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aMarkerColor_clicked()
{
if (m_annotationMarkers.size() == 0) {
return;
}
QColor newColor = QColorDialog::getColor(
m_annotationMarkers[m_annotationMarkerIndex].m_markerColor,
this,
tr("Select Color for marker"),
QColorDialog::DontUseNativeDialog
);
if (newColor.isValid()) // user clicked OK and selected a color
{
m_annotationMarkers[m_annotationMarkerIndex].m_markerColor = newColor;
displayAnnotationMarker();
}
}
void SpectrumMarkersDialog::on_aShowMarker_clicked(bool clicked)
{
if (m_annotationMarkers.size() == 0) {
return;
}
m_annotationMarkers[m_annotationMarkerIndex].m_show = clicked;
}
void SpectrumMarkersDialog::on_aMarkerText_editingFinished()
{
if (m_annotationMarkers.size() == 0) {
return;
}
m_annotationMarkers[m_annotationMarkerIndex].m_text = ui->aMarkerText->text();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aMarker_valueChanged(int value)
{
if (m_annotationMarkers.size() == 0) {
return;
}
m_annotationMarkerIndex = value;
displayAnnotationMarker();
}
void SpectrumMarkersDialog::on_aMarkerAdd_clicked()
{
m_annotationMarkers.append(SpectrumAnnotationMarker());
m_annotationMarkers.back().m_startFrequency = m_centerFrequency;
m_annotationMarkerIndex = m_annotationMarkers.size() - 1;
ui->aMarker->setMaximum(m_annotationMarkers.size() - 1);
displayAnnotationMarker();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aMarkerDel_clicked()
{
if (m_annotationMarkers.size() == 0) {
return;
}
m_annotationMarkers.removeAt(m_annotationMarkerIndex);
m_annotationMarkerIndex = m_annotationMarkerIndex < m_annotationMarkers.size() ?
m_annotationMarkerIndex : m_annotationMarkerIndex - 1;
ui->aMarker->setMaximum(m_annotationMarkers.size() - 1);
displayAnnotationMarker();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aMarkerBandwidth_changed(qint64 value)
{
if (m_annotationMarkers.size() == 0) {
return;
}
m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth = value < 0 ? 0 : value;
if (!m_annoFreqStartElseCenter)
{
m_annotationMarkers[m_annotationMarkerIndex].m_startFrequency = ui->aMarkerFrequency->getValue() -
(m_annotationMarkers[m_annotationMarkerIndex].m_bandwidth / 2);
}
displayAnnotationMarker();
emit updateAnnotations();
}
void SpectrumMarkersDialog::on_aMarkersImport_clicked()
{
QFileDialog fileDialog(nullptr, "Select .csv annotation markers file to read", "", "*.csv");
if (fileDialog.exec())
{
QStringList fileNames = fileDialog.selectedFiles();
if (fileNames.size() > 0)
{
QFile file(fileNames[0]);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&file);
QString error;
QHash<QString, int> colIndexes = CSV::readHeader(
in,
{"Start", "Width", "Text", "Show", "Red", "Green", "Blue"},
error
);
if (error.isEmpty())
{
QStringList cols;
int startCol = colIndexes.value("Start");
int widthCol = colIndexes.value("Width");
int textCol = colIndexes.value("Text");
int showCol = colIndexes.value("Show");
int redCol = colIndexes.value("Red");
int greenCol = colIndexes.value("Green");
int blueCol = colIndexes.value("Blue");
m_annotationMarkers.clear();
while (CSV::readRow(in, &cols))
{
m_annotationMarkers.push_back(SpectrumAnnotationMarker());
m_annotationMarkers.back().m_startFrequency = cols[startCol].toLongLong();
m_annotationMarkers.back().m_bandwidth = cols[widthCol].toUInt();
m_annotationMarkers.back().m_text = cols[textCol];
m_annotationMarkers.back().m_show = cols[showCol].toInt() != 0;
int r = cols[redCol].toInt();
int g = cols[greenCol].toInt();
int b = cols[blueCol].toInt();
m_annotationMarkers.back().m_markerColor = QColor(r, g, b);
}
m_annotationMarkerIndex = 0;
ui->aMarker->setMaximum(m_annotationMarkers.size() - 1);
displayAnnotationMarker();
emit updateAnnotations();
}
}
}
}
}
void SpectrumMarkersDialog::on_aMarkersExport_clicked()
{
QFileDialog fileDialog(nullptr, "Select file to write annotation markers to", "", "*.csv");
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
if (fileDialog.exec())
{
QStringList fileNames = fileDialog.selectedFiles();
if (fileNames.size() > 0)
{
QFile file(fileNames[0]);
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream stream;
stream.setDevice(&file);
stream << "Start,Width,Text,Show,Red,Green,Blue\n";
for (const auto &marker : m_annotationMarkers)
{
stream << marker.m_startFrequency << ","
<< marker.m_bandwidth << ","
<< marker.m_text << ","
<< (marker.m_show ? "1" : "0") << ","
<< marker.m_markerColor.red() << ","
<< marker.m_markerColor.green() << ","
<< marker.m_markerColor.blue() << "\n";
}
stream.flush();
file.close();
}
}
}
}
void SpectrumMarkersDialog::on_showSelect_currentIndexChanged(int index)
{
m_markersDisplay = (SpectrumSettings::MarkersDisplay) index;
emit updateMarkersDisplay();
}

View File

@ -37,6 +37,7 @@ public:
explicit SpectrumMarkersDialog(
QList<SpectrumHistogramMarker>& histogramMarkers,
QList<SpectrumWaterfallMarker>& waterfallMarkers,
QList<SpectrumAnnotationMarker>& annotationMarkers,
SpectrumSettings::MarkersDisplay& markersDisplay,
QWidget* parent = nullptr
);
@ -49,15 +50,19 @@ private:
Ui::SpectrumMarkersDialog* ui;
QList<SpectrumHistogramMarker>& m_histogramMarkers;
QList<SpectrumWaterfallMarker>& m_waterfallMarkers;
QList<SpectrumAnnotationMarker>& m_annotationMarkers;
SpectrumSettings::MarkersDisplay& m_markersDisplay;
int m_histogramMarkerIndex;
int m_waterfallMarkerIndex;
int m_annotationMarkerIndex;
qint64 m_centerFrequency;
float m_power;
float m_time;
bool m_annoFreqStartElseCenter;
void displayHistogramMarker();
void displayWaterfallMarker();
void displayAnnotationMarker();
void displayTime(float time);
float getTime() const;
@ -73,6 +78,7 @@ private slots:
void on_markerDel_clicked();
void on_powerMode_currentIndexChanged(int index);
void on_powerHoldReset_clicked();
void on_wMarkerFrequency_changed(qint64 value);
void on_timeCoarse_valueChanged(int value);
void on_timeFine_valueChanged(int value);
@ -84,11 +90,33 @@ private slots:
void on_wSetReference_clicked();
void on_wMarkerAdd_clicked();
void on_wMarkerDel_clicked();
void on_aMarkerToggleFrequency_toggled(bool checked);
void on_aMarkerFrequency_changed(qint64 value);
void on_aCenterFrequency_clicked();
void on_aMakerDuplicate_clicked();
void on_aMakersSort_clicked();
void on_aMarkerColor_clicked();
void on_aShowMarker_clicked(bool clicked);
void on_aMarkerText_editingFinished();
void on_aMarker_valueChanged(int value);
void on_aMarkerAdd_clicked();
void on_aMarkerDel_clicked();
void on_aMarkerBandwidth_changed(qint64 value);
void on_aMarkersExport_clicked();
void on_aMarkersImport_clicked();
static bool annotationMarkerLessThan(const SpectrumAnnotationMarker& m1, const SpectrumAnnotationMarker& m2) {
return m1.m_startFrequency < m2.m_startFrequency;
}
void on_showSelect_currentIndexChanged(int index);
signals:
void updateHistogram();
void updateWaterfall();
void updateAnnotations();
void updateMarkersDisplay();
};
#endif // SDRBASE_GUI_SPECTRUMMARKERSDIALOG_H_

View File

@ -6,10 +6,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>418</width>
<height>237</height>
<width>480</width>
<height>300</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>480</width>
<height>300</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
@ -23,13 +29,13 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="hisTab">
<attribute name="title">
<string>Hist</string>
</attribute>
<widget class="QWidget" name="">
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
@ -39,6 +45,9 @@
</rect>
</property>
<layout class="QVBoxLayout" name="HMarkerLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="HMarkerPosLayout">
<item>
@ -488,6 +497,9 @@
</rect>
</property>
<layout class="QVBoxLayout" name="WMarkerLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="WMarkerPosLayout">
<item>
@ -987,6 +999,665 @@
</layout>
</widget>
</widget>
<widget class="QWidget" name="anoTab">
<attribute name="title">
<string>Anno</string>
</attribute>
<widget class="QWidget" name="layoutWidget_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>451</width>
<height>151</height>
</rect>
</property>
<layout class="QVBoxLayout" name="AMarkerLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="AMarkerGeneralLayout">
<item>
<widget class="QLabel" name="aMarkerLabel">
<property name="minimumSize">
<size>
<width>24</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Mk</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aMarkerIndexText">
<property name="minimumSize">
<size>
<width>15</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Marker index</string>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="aMarker">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Marker index selection</string>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="AMarkerAddRemoveLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="aMarkerAdd">
<property name="maximumSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>190</red>
<green>190</green>
<blue>190</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="toolTip">
<string>Add a new marker</string>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="aMarkerDel">
<property name="maximumSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>190</red>
<green>190</green>
<blue>190</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="toolTip">
<string>Remove current marker</string>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="ClickableLabel" name="aMarkerColor">
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="toolTip">
<string>Current marker color (click to change)</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="aShowMarker">
<property name="toolTip">
<string>Show this marker</string>
</property>
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="aMarkerText">
<property name="toolTip">
<string>Marker text</string>
</property>
<property name="maxLength">
<number>30</number>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="aMarkersExport">
<property name="toolTip">
<string>Export annotation marks to .csv file</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/export.png</normaloff>:/export.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="aMarkersImport">
<property name="toolTip">
<string>Import annotation marks from .csv file</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/import.png</normaloff>:/import.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="AMarkerStartLayout">
<item>
<widget class="QToolButton" name="aMarkerToggleFrequency">
<property name="text">
<string>Start</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="ValueDialZ" name="aMarkerFrequency" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Marker start frequency (Hz)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aMarkerFrequencyUnits">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Marker frequency (Hz)</string>
</property>
<property name="text">
<string>Hz</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="aCenterFrequency">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Set marker frequency to center frequency</string>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="aMakerDuplicate">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Duplicate current marker</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/duplicate.png</normaloff>:/duplicate.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="aMakersSort">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Sort markers by increasing start frequency</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/sort.png</normaloff>:/sort.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="AMarkeStopLayout">
<item>
<widget class="QLabel" name="aMarkerFreqLabel">
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Cent</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aMarkerFreqText">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="toolTip">
<string>Marker stop frequency (Hz)</string>
</property>
<property name="text">
<string>0,000,000,000</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aMarkerFreqFrequencyUnits">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Marker frequency (Hz)</string>
</property>
<property name="text">
<string>Hz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="aMarkerStopLabel">
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aMarkerStopText">
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="toolTip">
<string>Marker stop frequency (Hz)</string>
</property>
<property name="text">
<string>0,000,000,000</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aMarkerStopFrequencyUnits">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Marker frequency (Hz)</string>
</property>
<property name="text">
<string>Hz</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="AMarkerOptionsLayout">
<item>
<widget class="QLabel" name="aBandwidthLabel">
<property name="minimumSize">
<size>
<width>15</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>BW</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="ValueDialZ" name="aMarkerBandwidth" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Marker width (Hz)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aMarkerBandwidthUnits">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Marker frequency (Hz)</string>
</property>
<property name="text">
<string>Hz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
<item>
@ -1016,6 +1687,11 @@
<string>Spec</string>
</property>
</item>
<item>
<property name="text">
<string>Anno</string>
</property>
</item>
</widget>
</item>
<item>

View File

@ -1181,7 +1181,6 @@ bool MainWindow::handleMessage(const Message& cmd)
{
int nbMIMOChannels = deviceUI->getNumberOfAvailableMIMOChannels();
int nbRxChannels = deviceUI->getNumberOfAvailableRxChannels();
int nbTxChannels = deviceUI->getNumberOfAvailableTxChannels();
int direction = notif.getDirection();
if (direction == 2) {

View File

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
<file>sort.png</file>
<file>audio_mic.png</file>
<file>info.png</file>
<file>darklight.png</file>

BIN
sdrgui/resources/sort.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

View File

@ -17,7 +17,7 @@ SpectrumHistogramMarker:
* 2 - Max power
markerColor:
type: integer
description: Color in 8 bit RGB serie
description: Color in 8 bit BGR serie
show:
type: integer
description: >
@ -37,7 +37,25 @@ SpectrumWaterfallMarker:
description: Time shift in seconds
markerColor:
type: integer
description: Color in 8 bit RGB serie
description: Color in 8 bit BGR serie
show:
type: integer
description: >
Boolean - Marker display state
* 0 - Hidden
* 1 - Visible
SpectrumAnnotationMarker:
description: Spectrum annotation marker settings
properties:
startFrequency:
type: integer
format: int64
bandwidth:
type: integer
markerColor:
type: integer
description: Color in 8 bit BGR serie
show:
type: integer
description: >
@ -129,3 +147,7 @@ GLSpectrum:
type: array
items:
$ref: "http://swgserver:8081/api/swagger/include/GLSpectrum.yaml#/SpectrumWaterfallMarker"
annotationMarkers:
type: array
items:
$ref: "http://swgserver:8081/api/swagger/include/GLSpectrum.yaml#/SpectrumAnnotationMarker"

View File

@ -6162,6 +6162,12 @@ margin-bottom: 20px;
"items" : {
"$ref" : "#/definitions/SpectrumWaterfallMarker"
}
},
"annotationMarkers" : {
"type" : "array",
"items" : {
"$ref" : "#/definitions/SpectrumAnnotationMarker"
}
}
},
"description" : "GLSpectrumGUI settings"
@ -11782,6 +11788,26 @@ margin-bottom: 20px;
}
},
"description" : "SoapySDR"
};
defs.SpectrumAnnotationMarker = {
"properties" : {
"startFrequency" : {
"type" : "integer",
"format" : "int64"
},
"bandwidth" : {
"type" : "integer"
},
"markerColor" : {
"type" : "integer",
"description" : "Color in 8 bit BGR serie"
},
"show" : {
"type" : "integer",
"description" : "Boolean - Marker display state\n * 0 - Hidden\n * 1 - Visible\n"
}
},
"description" : "Spectrum annotation marker settings"
};
defs.SpectrumHistogramMarker = {
"properties" : {
@ -11800,7 +11826,7 @@ margin-bottom: 20px;
},
"markerColor" : {
"type" : "integer",
"description" : "Color in 8 bit RGB serie"
"description" : "Color in 8 bit BGR serie"
},
"show" : {
"type" : "integer",
@ -11854,7 +11880,7 @@ margin-bottom: 20px;
},
"markerColor" : {
"type" : "integer",
"description" : "Color in 8 bit RGB serie"
"description" : "Color in 8 bit BGR serie"
},
"show" : {
"type" : "integer",
@ -51943,7 +51969,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2022-01-15T03:12:23.419+01:00
Generated 2022-01-15T23:01:29.100+01:00
</div>
</div>
</div>

View File

@ -84,6 +84,8 @@ SWGGLSpectrum::SWGGLSpectrum() {
m_histogram_markers_isSet = false;
waterfall_markers = nullptr;
m_waterfall_markers_isSet = false;
annotation_markers = nullptr;
m_annotation_markers_isSet = false;
}
SWGGLSpectrum::~SWGGLSpectrum() {
@ -148,6 +150,8 @@ SWGGLSpectrum::init() {
m_histogram_markers_isSet = false;
waterfall_markers = new QList<SWGSpectrumWaterfallMarker*>();
m_waterfall_markers_isSet = false;
annotation_markers = new QList<SWGSpectrumAnnotationMarker*>();
m_annotation_markers_isSet = false;
}
void
@ -194,6 +198,13 @@ SWGGLSpectrum::cleanup() {
}
delete waterfall_markers;
}
if(annotation_markers != nullptr) {
auto arr = annotation_markers;
for(auto o: *arr) {
delete o;
}
delete annotation_markers;
}
}
SWGGLSpectrum*
@ -263,6 +274,8 @@ SWGGLSpectrum::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&histogram_markers, pJson["histogramMarkers"], "QList", "SWGSpectrumHistogramMarker");
::SWGSDRangel::setValue(&waterfall_markers, pJson["waterfallMarkers"], "QList", "SWGSpectrumWaterfallMarker");
::SWGSDRangel::setValue(&annotation_markers, pJson["annotationMarkers"], "QList", "SWGSpectrumAnnotationMarker");
}
QString
@ -363,6 +376,9 @@ SWGGLSpectrum::asJsonObject() {
if(waterfall_markers && waterfall_markers->size() > 0){
toJsonArray((QList<void*>*)waterfall_markers, obj, "waterfallMarkers", "SWGSpectrumWaterfallMarker");
}
if(annotation_markers && annotation_markers->size() > 0){
toJsonArray((QList<void*>*)annotation_markers, obj, "annotationMarkers", "SWGSpectrumAnnotationMarker");
}
return obj;
}
@ -647,6 +663,16 @@ SWGGLSpectrum::setWaterfallMarkers(QList<SWGSpectrumWaterfallMarker*>* waterfall
this->m_waterfall_markers_isSet = true;
}
QList<SWGSpectrumAnnotationMarker*>*
SWGGLSpectrum::getAnnotationMarkers() {
return annotation_markers;
}
void
SWGGLSpectrum::setAnnotationMarkers(QList<SWGSpectrumAnnotationMarker*>* annotation_markers) {
this->annotation_markers = annotation_markers;
this->m_annotation_markers_isSet = true;
}
bool
SWGGLSpectrum::isSet(){
@ -736,6 +762,9 @@ SWGGLSpectrum::isSet(){
if(waterfall_markers && (waterfall_markers->size() > 0)){
isObjectUpdated = true; break;
}
if(annotation_markers && (annotation_markers->size() > 0)){
isObjectUpdated = true; break;
}
}while(false);
return isObjectUpdated;
}

View File

@ -22,6 +22,7 @@
#include <QJsonObject>
#include "SWGSpectrumAnnotationMarker.h"
#include "SWGSpectrumHistogramMarker.h"
#include "SWGSpectrumWaterfallMarker.h"
#include <QList>
@ -129,6 +130,9 @@ public:
QList<SWGSpectrumWaterfallMarker*>* getWaterfallMarkers();
void setWaterfallMarkers(QList<SWGSpectrumWaterfallMarker*>* waterfall_markers);
QList<SWGSpectrumAnnotationMarker*>* getAnnotationMarkers();
void setAnnotationMarkers(QList<SWGSpectrumAnnotationMarker*>* annotation_markers);
virtual bool isSet() override;
@ -217,6 +221,9 @@ private:
QList<SWGSpectrumWaterfallMarker*>* waterfall_markers;
bool m_waterfall_markers_isSet;
QList<SWGSpectrumAnnotationMarker*>* annotation_markers;
bool m_annotation_markers_isSet;
};
}

View File

@ -264,6 +264,7 @@
#include "SWGSoapySDRInputSettings.h"
#include "SWGSoapySDROutputSettings.h"
#include "SWGSoapySDRReport.h"
#include "SWGSpectrumAnnotationMarker.h"
#include "SWGSpectrumHistogramMarker.h"
#include "SWGSpectrumServer.h"
#include "SWGSpectrumServer_clients.h"
@ -1564,6 +1565,11 @@ namespace SWGSDRangel {
obj->init();
return obj;
}
if(QString("SWGSpectrumAnnotationMarker").compare(type) == 0) {
SWGSpectrumAnnotationMarker *obj = new SWGSpectrumAnnotationMarker();
obj->init();
return obj;
}
if(QString("SWGSpectrumHistogramMarker").compare(type) == 0) {
SWGSpectrumHistogramMarker *obj = new SWGSpectrumHistogramMarker();
obj->init();

View File

@ -0,0 +1,177 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 6.0.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
#include "SWGSpectrumAnnotationMarker.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGSpectrumAnnotationMarker::SWGSpectrumAnnotationMarker(QString* json) {
init();
this->fromJson(*json);
}
SWGSpectrumAnnotationMarker::SWGSpectrumAnnotationMarker() {
start_frequency = 0L;
m_start_frequency_isSet = false;
bandwidth = 0;
m_bandwidth_isSet = false;
marker_color = 0;
m_marker_color_isSet = false;
show = 0;
m_show_isSet = false;
}
SWGSpectrumAnnotationMarker::~SWGSpectrumAnnotationMarker() {
this->cleanup();
}
void
SWGSpectrumAnnotationMarker::init() {
start_frequency = 0L;
m_start_frequency_isSet = false;
bandwidth = 0;
m_bandwidth_isSet = false;
marker_color = 0;
m_marker_color_isSet = false;
show = 0;
m_show_isSet = false;
}
void
SWGSpectrumAnnotationMarker::cleanup() {
}
SWGSpectrumAnnotationMarker*
SWGSpectrumAnnotationMarker::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGSpectrumAnnotationMarker::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&start_frequency, pJson["startFrequency"], "qint64", "");
::SWGSDRangel::setValue(&bandwidth, pJson["bandwidth"], "qint32", "");
::SWGSDRangel::setValue(&marker_color, pJson["markerColor"], "qint32", "");
::SWGSDRangel::setValue(&show, pJson["show"], "qint32", "");
}
QString
SWGSpectrumAnnotationMarker::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGSpectrumAnnotationMarker::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_start_frequency_isSet){
obj->insert("startFrequency", QJsonValue(start_frequency));
}
if(m_bandwidth_isSet){
obj->insert("bandwidth", QJsonValue(bandwidth));
}
if(m_marker_color_isSet){
obj->insert("markerColor", QJsonValue(marker_color));
}
if(m_show_isSet){
obj->insert("show", QJsonValue(show));
}
return obj;
}
qint64
SWGSpectrumAnnotationMarker::getStartFrequency() {
return start_frequency;
}
void
SWGSpectrumAnnotationMarker::setStartFrequency(qint64 start_frequency) {
this->start_frequency = start_frequency;
this->m_start_frequency_isSet = true;
}
qint32
SWGSpectrumAnnotationMarker::getBandwidth() {
return bandwidth;
}
void
SWGSpectrumAnnotationMarker::setBandwidth(qint32 bandwidth) {
this->bandwidth = bandwidth;
this->m_bandwidth_isSet = true;
}
qint32
SWGSpectrumAnnotationMarker::getMarkerColor() {
return marker_color;
}
void
SWGSpectrumAnnotationMarker::setMarkerColor(qint32 marker_color) {
this->marker_color = marker_color;
this->m_marker_color_isSet = true;
}
qint32
SWGSpectrumAnnotationMarker::getShow() {
return show;
}
void
SWGSpectrumAnnotationMarker::setShow(qint32 show) {
this->show = show;
this->m_show_isSet = true;
}
bool
SWGSpectrumAnnotationMarker::isSet(){
bool isObjectUpdated = false;
do{
if(m_start_frequency_isSet){
isObjectUpdated = true; break;
}
if(m_bandwidth_isSet){
isObjectUpdated = true; break;
}
if(m_marker_color_isSet){
isObjectUpdated = true; break;
}
if(m_show_isSet){
isObjectUpdated = true; break;
}
}while(false);
return isObjectUpdated;
}
}

View File

@ -0,0 +1,76 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 6.0.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/*
* SWGSpectrumAnnotationMarker.h
*
* Spectrum annotation marker settings
*/
#ifndef SWGSpectrumAnnotationMarker_H_
#define SWGSpectrumAnnotationMarker_H_
#include <QJsonObject>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGSpectrumAnnotationMarker: public SWGObject {
public:
SWGSpectrumAnnotationMarker();
SWGSpectrumAnnotationMarker(QString* json);
virtual ~SWGSpectrumAnnotationMarker();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGSpectrumAnnotationMarker* fromJson(QString &jsonString) override;
qint64 getStartFrequency();
void setStartFrequency(qint64 start_frequency);
qint32 getBandwidth();
void setBandwidth(qint32 bandwidth);
qint32 getMarkerColor();
void setMarkerColor(qint32 marker_color);
qint32 getShow();
void setShow(qint32 show);
virtual bool isSet() override;
private:
qint64 start_frequency;
bool m_start_frequency_isSet;
qint32 bandwidth;
bool m_bandwidth_isSet;
qint32 marker_color;
bool m_marker_color_isSet;
qint32 show;
bool m_show_isSet;
};
}
#endif /* SWGSpectrumAnnotationMarker_H_ */