mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-02-03 09:44:01 -05:00
Add AvailableChannelOrFeatureHandler for handling lists of channels, features and message pipes to them.
This commit is contained in:
parent
607d7db702
commit
483e338614
@ -67,6 +67,7 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) :
|
||||
m_basebandSink(nullptr),
|
||||
m_running(false),
|
||||
m_basebandSampleRate(0),
|
||||
m_availableChannelHandler({}),
|
||||
m_scanDeviceSetIndex(0),
|
||||
m_scanChannelIndex(0),
|
||||
m_state(IDLE),
|
||||
@ -95,19 +96,8 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) :
|
||||
|
||||
start();
|
||||
|
||||
scanAvailableChannels();
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
this,
|
||||
&FreqScanner::handleChannelAdded
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelRemoved,
|
||||
this,
|
||||
&FreqScanner::handleChannelRemoved
|
||||
);
|
||||
QObject::connect(&m_availableChannelHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &FreqScanner::channelsChanged);
|
||||
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||
|
||||
m_timeoutTimer.callOnTimeout(this, &FreqScanner::timeout);
|
||||
}
|
||||
@ -708,7 +698,7 @@ void FreqScanner::applySettings(const FreqScannerSettings& settings, const QStri
|
||||
m_deviceAPI->removeChannelSink(this, m_settings.m_streamIndex);
|
||||
m_deviceAPI->addChannelSink(this, settings.m_streamIndex);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
scanAvailableChannels(); // re-scan
|
||||
//FIXME:scanAvailableChannels(); // re-scan
|
||||
emit streamIndexChanged(settings.m_streamIndex);
|
||||
}
|
||||
}
|
||||
@ -1116,186 +1106,18 @@ void FreqScanner::handleIndexInDeviceSetChanged(int index)
|
||||
m_basebandSink->setFifoLabel(fifoLabel);
|
||||
}
|
||||
|
||||
void FreqScanner::scanAvailableChannels()
|
||||
void FreqScanner::channelsChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
m_availableChannels.clear();
|
||||
|
||||
DSPDeviceSourceEngine* deviceSourceEngine = getDeviceAPI()->getDeviceSourceEngine();
|
||||
|
||||
if (deviceSourceEngine)
|
||||
{
|
||||
for (int chi = 0; chi < getDeviceAPI()->getNbSinkChannels(); chi++) // Rx channels
|
||||
{
|
||||
ChannelAPI* channel = getDeviceAPI()->getChanelSinkAPIAt(chi);
|
||||
|
||||
if (channel->getIndexInDeviceSet() == getIndexInDeviceSet()) { // Exclude oneself
|
||||
continue;
|
||||
}
|
||||
|
||||
FreqScannerSettings::AvailableChannel availableChannel =
|
||||
FreqScannerSettings::AvailableChannel{
|
||||
channel->getDeviceSetIndex(),
|
||||
channel->getIndexInDeviceSet(),
|
||||
-1
|
||||
};
|
||||
m_availableChannels[channel] = availableChannel;
|
||||
QObject::connect(
|
||||
channel,
|
||||
&ChannelAPI::streamIndexChanged,
|
||||
[=](int streamIndex){
|
||||
this->handleChannelStreamIndexChanged(streamIndex, channel);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DSPDeviceMIMOEngine *deviceMIMOEngine = getDeviceAPI()->getDeviceMIMOEngine();
|
||||
|
||||
if (deviceMIMOEngine)
|
||||
{
|
||||
for (int chi = 0; chi < getDeviceAPI()->getNbSinkChannels(); chi++) // Rx channels
|
||||
{
|
||||
ChannelAPI* channel = getDeviceAPI()->getChanelSinkAPIAt(chi);
|
||||
|
||||
if (channel->getIndexInDeviceSet() == getIndexInDeviceSet()) { // Exclude oneself
|
||||
continue;
|
||||
}
|
||||
|
||||
// Single Rx on the same I/Q stream
|
||||
if ((channel->getNbSinkStreams() == 1)
|
||||
&& (channel->getNbSourceStreams() == 0)
|
||||
&& (channel->getStreamIndex() == m_settings.m_streamIndex))
|
||||
{
|
||||
FreqScannerSettings::AvailableChannel availableChannel =
|
||||
FreqScannerSettings::AvailableChannel{
|
||||
channel->getDeviceSetIndex(),
|
||||
channel->getIndexInDeviceSet(),
|
||||
channel->getStreamIndex()
|
||||
};
|
||||
m_availableChannels[channel] = availableChannel;
|
||||
QObject::connect(
|
||||
channel,
|
||||
&ChannelAPI::streamIndexChanged,
|
||||
[=](int streamIndex){
|
||||
this->handleChannelStreamIndexChanged(streamIndex, channel);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notifyUpdateChannels();
|
||||
m_availableChannels = m_availableChannelHandler.getAvailableChannelOrFeatureList();
|
||||
notifyUpdateChannels(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
void FreqScanner::handleChannelAdded(int deviceSetIndex, ChannelAPI* channel)
|
||||
{
|
||||
if (deviceSetIndex != getDeviceSetIndex()) { // Can control channels only in the same device set
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("FreqScanner::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)",
|
||||
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
||||
DSPDeviceSourceEngine* deviceSourceEngine = getDeviceAPI()->getDeviceSourceEngine();
|
||||
|
||||
if (deviceSourceEngine)
|
||||
{
|
||||
FreqScannerSettings::AvailableChannel availableChannel =
|
||||
FreqScannerSettings::AvailableChannel{ deviceSetIndex, channel->getIndexInDeviceSet(), -1};
|
||||
m_availableChannels[channel] = availableChannel;
|
||||
QObject::connect(
|
||||
channel,
|
||||
&ChannelAPI::streamIndexChanged,
|
||||
[=](int streamIndex){
|
||||
this->handleChannelStreamIndexChanged(streamIndex, channel);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
DSPDeviceMIMOEngine *deviceMIMOEngine = getDeviceAPI()->getDeviceMIMOEngine();
|
||||
|
||||
if (deviceMIMOEngine
|
||||
&& (channel->getNbSinkStreams() == 1)
|
||||
&& (channel->getNbSourceStreams() == 0)
|
||||
&& (channel->getStreamIndex() == m_settings.m_streamIndex))
|
||||
{
|
||||
FreqScannerSettings::AvailableChannel availableChannel =
|
||||
FreqScannerSettings::AvailableChannel{
|
||||
deviceSetIndex,
|
||||
channel->getIndexInDeviceSet(),
|
||||
channel->getStreamIndex()
|
||||
};
|
||||
m_availableChannels[channel] = availableChannel;
|
||||
QObject::connect(
|
||||
channel,
|
||||
&ChannelAPI::streamIndexChanged,
|
||||
[=](int streamIndex){
|
||||
this->handleChannelStreamIndexChanged(streamIndex, channel);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
notifyUpdateChannels();
|
||||
}
|
||||
|
||||
void FreqScanner::handleChannelRemoved(int deviceSetIndex, ChannelAPI* channel)
|
||||
{
|
||||
if (deviceSetIndex != getDeviceSetIndex()) { // Can control channels only in the same device set
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("FreqScanner::handleChannelRemoved: deviceSetIndex: %d:%d channel: %s (%p)",
|
||||
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
||||
DSPDeviceSourceEngine* deviceSourceEngine = getDeviceAPI()->getDeviceSourceEngine();
|
||||
DSPDeviceMIMOEngine *deviceMIMOEngine = getDeviceAPI()->getDeviceMIMOEngine();
|
||||
|
||||
if (deviceSourceEngine || deviceMIMOEngine) {
|
||||
m_availableChannels.remove(channel);
|
||||
}
|
||||
|
||||
notifyUpdateChannels();
|
||||
}
|
||||
|
||||
void FreqScanner::handleChannelStreamIndexChanged(int streamIndex, ChannelAPI* channel)
|
||||
{
|
||||
qDebug("FreqScanner::handleChannelStreamIndexChanged: channel: %s (%p) stream: %d",
|
||||
qPrintable(channel->getURI()), channel, streamIndex);
|
||||
if (streamIndex != m_settings.m_streamIndex) // channel has moved to another I/Q stream
|
||||
{
|
||||
m_availableChannels.remove(channel);
|
||||
notifyUpdateChannels();
|
||||
}
|
||||
else if (!m_availableChannels.contains(channel)) // if channel has been tracked before put back it in the list
|
||||
{
|
||||
FreqScannerSettings::AvailableChannel availableChannel =
|
||||
FreqScannerSettings::AvailableChannel{
|
||||
getDeviceSetIndex(),
|
||||
channel->getIndexInDeviceSet(),
|
||||
channel->getStreamIndex()
|
||||
};
|
||||
m_availableChannels[channel] = availableChannel;
|
||||
notifyUpdateChannels();
|
||||
}
|
||||
}
|
||||
|
||||
void FreqScanner::notifyUpdateChannels()
|
||||
void FreqScanner::notifyUpdateChannels(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportChannels* msgToGUI = MsgReportChannels::create();
|
||||
QList<FreqScannerSettings::AvailableChannel>& msgChannels = msgToGUI->getChannels();
|
||||
QHash<ChannelAPI*, FreqScannerSettings::AvailableChannel>::iterator it = m_availableChannels.begin();
|
||||
|
||||
for (; it != m_availableChannels.end(); ++it)
|
||||
{
|
||||
FreqScannerSettings::AvailableChannel msgChannel =
|
||||
FreqScannerSettings::AvailableChannel{
|
||||
it->m_deviceSetIndex,
|
||||
it->m_channelIndex,
|
||||
it->m_streamIndex
|
||||
};
|
||||
msgChannels.push_back(msgChannel);
|
||||
}
|
||||
|
||||
MsgReportChannels* msgToGUI = MsgReportChannels::create(renameFrom, renameTo);
|
||||
msgToGUI->getChannels() = m_availableChannels;
|
||||
getMessageQueueToGUI()->push(msgToGUI);
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "util/message.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
|
||||
#include "freqscannerbaseband.h"
|
||||
#include "freqscannersettings.h"
|
||||
@ -71,17 +72,23 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
QList<FreqScannerSettings::AvailableChannel>& getChannels() { return m_channels; }
|
||||
AvailableChannelOrFeatureList& getChannels() { return m_channels; }
|
||||
const QStringList& getRenameFrom() const { return m_renameFrom; }
|
||||
const QStringList& getRenameTo() const { return m_renameTo; }
|
||||
|
||||
static MsgReportChannels* create() {
|
||||
return new MsgReportChannels();
|
||||
static MsgReportChannels* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||
return new MsgReportChannels(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
private:
|
||||
QList<FreqScannerSettings::AvailableChannel> m_channels;
|
||||
AvailableChannelOrFeatureList m_channels;
|
||||
QStringList m_renameFrom;
|
||||
QStringList m_renameTo;
|
||||
|
||||
MsgReportChannels() :
|
||||
Message()
|
||||
MsgReportChannels(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||
Message(),
|
||||
m_renameFrom(renameFrom),
|
||||
m_renameTo(renameTo)
|
||||
{}
|
||||
};
|
||||
|
||||
@ -369,7 +376,8 @@ private:
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
|
||||
QHash<ChannelAPI*, FreqScannerSettings::AvailableChannel> m_availableChannels;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||
|
||||
unsigned int m_scanDeviceSetIndex;
|
||||
unsigned int m_scanChannelIndex;
|
||||
@ -402,8 +410,8 @@ private:
|
||||
);
|
||||
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
|
||||
|
||||
void scanAvailableChannels();
|
||||
void notifyUpdateChannels();
|
||||
//void scanAvailableChannels();
|
||||
void notifyUpdateChannels(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void startScan();
|
||||
void stopScan();
|
||||
void initScan();
|
||||
@ -416,9 +424,7 @@ private:
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleIndexInDeviceSetChanged(int index);
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI* channel);
|
||||
void handleChannelRemoved(int deviceSetIndex, ChannelAPI* channel);
|
||||
void handleChannelStreamIndexChanged(int streamIndex, ChannelAPI* channel);
|
||||
void channelsChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void timeout();
|
||||
|
||||
};
|
||||
|
@ -118,8 +118,7 @@ bool FreqScannerGUI::handleMessage(const Message& message)
|
||||
else if (FreqScanner::MsgReportChannels::match(message))
|
||||
{
|
||||
FreqScanner::MsgReportChannels& report = (FreqScanner::MsgReportChannels&)message;
|
||||
m_availableChannels = report.getChannels();
|
||||
updateChannelsList(m_availableChannels);
|
||||
updateChannelsList(report.getChannels(), report.getRenameFrom(), report.getRenameTo());
|
||||
return true;
|
||||
}
|
||||
else if (FreqScanner::MsgStatus::match(message))
|
||||
@ -212,7 +211,7 @@ bool FreqScannerGUI::handleMessage(const Message& message)
|
||||
return false;
|
||||
}
|
||||
|
||||
void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QList<FreqScannerSettings::AvailableChannel>& channels, const QString& channel, bool empty)
|
||||
void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const AvailableChannelOrFeatureList& channels, const QString& channel, bool empty)
|
||||
{
|
||||
combo->blockSignals(true);
|
||||
combo->clear();
|
||||
@ -223,17 +222,8 @@ void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QList<FreqScann
|
||||
for (const auto& channel : channels)
|
||||
{
|
||||
// Add channels in this device set, other than ourself (Don't use ChannelGUI::getDeviceSetIndex()/getIndex() as not valid when this is first called)
|
||||
if ((channel.m_deviceSetIndex == m_freqScanner->getDeviceSetIndex()) && (channel.m_channelIndex != m_freqScanner->getIndexInDeviceSet()))
|
||||
{
|
||||
QString name;
|
||||
|
||||
if (channel.m_streamIndex < 0) { // Rx
|
||||
name = QString("R%1:%2").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex);
|
||||
} else { // MIMO
|
||||
name = QString("M%1:%2.%3").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex).arg(channel.m_streamIndex);
|
||||
}
|
||||
|
||||
combo->addItem(name);
|
||||
if ((channel.m_superIndex == m_freqScanner->getDeviceSetIndex()) && (channel.m_index != m_freqScanner->getIndexInDeviceSet())) {
|
||||
combo->addItem(channel.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,8 +240,29 @@ void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QList<FreqScann
|
||||
combo->blockSignals(false);
|
||||
}
|
||||
|
||||
void FreqScannerGUI::updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels)
|
||||
void FreqScannerGUI::updateChannelsList(const AvailableChannelOrFeatureList& channels, const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
m_availableChannels = channels;
|
||||
|
||||
// Update channel setting if it has been renamed
|
||||
if (renameFrom.contains(m_settings.m_channel))
|
||||
{
|
||||
m_settings.m_channel = renameTo[renameFrom.indexOf(m_settings.m_channel)];
|
||||
applySetting("channel");
|
||||
}
|
||||
bool rename = false;
|
||||
for (auto& setting : m_settings.m_frequencySettings)
|
||||
{
|
||||
if (renameFrom.contains(setting.m_channel))
|
||||
{
|
||||
setting.m_channel = renameTo[renameFrom.indexOf(setting.m_channel)];
|
||||
rename = true;
|
||||
}
|
||||
}
|
||||
if (rename) {
|
||||
applySetting("frequencySettings");
|
||||
}
|
||||
|
||||
updateChannelsCombo(ui->channels, channels, m_settings.m_channel, false);
|
||||
|
||||
for (int row = 0; row < ui->table->rowCount(); row++)
|
||||
@ -515,10 +526,12 @@ void FreqScannerGUI::applySetting(const QString& settingsKey)
|
||||
|
||||
void FreqScannerGUI::applySettings(const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
m_settingsKeys.append(settingsKeys);
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
FreqScanner::MsgConfigureFreqScanner* message = FreqScanner::MsgConfigureFreqScanner::create(m_settings, settingsKeys, force);
|
||||
FreqScanner::MsgConfigureFreqScanner* message = FreqScanner::MsgConfigureFreqScanner::create(m_settings, m_settingsKeys, force);
|
||||
m_freqScanner->getInputMessageQueue()->push(message);
|
||||
m_settingsKeys.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ private:
|
||||
ChannelMarker m_channelMarker;
|
||||
RollupState m_rollupState;
|
||||
FreqScannerSettings m_settings;
|
||||
QList<QString> m_settingsKeys;
|
||||
qint64 m_deviceCenterFrequency;
|
||||
bool m_doApplySettings;
|
||||
|
||||
@ -82,7 +83,7 @@ private:
|
||||
|
||||
QMenu *m_menu;
|
||||
|
||||
QList<FreqScannerSettings::AvailableChannel> m_availableChannels;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
|
||||
explicit FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||
virtual ~FreqScannerGUI();
|
||||
@ -98,8 +99,8 @@ private:
|
||||
void addRow(const FreqScannerSettings::FrequencySettings& frequencySettings);
|
||||
void updateAnnotation(int row);
|
||||
void updateAnnotations();
|
||||
void updateChannelsCombo(QComboBox *combo, const QList<FreqScannerSettings::AvailableChannel>& channels, const QString& channel, bool empty);
|
||||
void updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels);
|
||||
void updateChannelsCombo(QComboBox *combo, const AvailableChannelOrFeatureList& channels, const QString& channel, bool empty);
|
||||
void updateChannelsList(const AvailableChannelOrFeatureList& channels, const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void setAllEnabled(bool enable);
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
|
@ -31,17 +31,6 @@ class ChannelAPI;
|
||||
|
||||
struct FreqScannerSettings
|
||||
{
|
||||
struct AvailableChannel
|
||||
{
|
||||
int m_deviceSetIndex;
|
||||
int m_channelIndex;
|
||||
int m_streamIndex;
|
||||
|
||||
AvailableChannel() = default;
|
||||
AvailableChannel(const AvailableChannel&) = default;
|
||||
AvailableChannel& operator=(const AvailableChannel&) = default;
|
||||
};
|
||||
|
||||
struct FrequencySettings {
|
||||
qint64 m_frequency;
|
||||
bool m_enabled;
|
||||
|
@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2021 Jon Beniston, M7RCE //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -67,10 +67,12 @@ const char * const RadioAstronomy::m_channelIdURI = "sdrangel.channel.radioastro
|
||||
const char * const RadioAstronomy::m_channelId = "RadioAstronomy";
|
||||
|
||||
RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) :
|
||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_basebandSampleRate(0),
|
||||
m_sweeping(false)
|
||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_basebandSampleRate(0),
|
||||
m_sweeping(false),
|
||||
m_availableFeatureHandler({"sdrangel.feature.startracker"}, QStringList{"startracker.target"}),
|
||||
m_availableRotatorHandler({"sdrangel.feature.gs232controller"})
|
||||
{
|
||||
qDebug("RadioAstronomy::RadioAstronomy");
|
||||
setObjectName(m_channelId);
|
||||
@ -105,17 +107,26 @@ RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) :
|
||||
&RadioAstronomy::handleIndexInDeviceSetChanged
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureAdded,
|
||||
&m_availableFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&RadioAstronomy::handleFeatureAdded
|
||||
&RadioAstronomy::handleFeatureMessageQueue
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureRemoved,
|
||||
&m_availableFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&RadioAstronomy::handleFeatureRemoved
|
||||
&RadioAstronomy::featuresChanged
|
||||
);
|
||||
m_availableFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||
|
||||
QObject::connect(
|
||||
&m_availableRotatorHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&RadioAstronomy::rotatorsChanged
|
||||
);
|
||||
m_availableRotatorHandler.scanAvailableChannelsAndFeatures();
|
||||
|
||||
m_sweepTimer.setSingleShot(true);
|
||||
}
|
||||
@ -123,17 +134,20 @@ RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) :
|
||||
RadioAstronomy::~RadioAstronomy()
|
||||
{
|
||||
qDebug("RadioAstronomy::~RadioAstronomy");
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureRemoved,
|
||||
QObject::disconnect(&m_availableFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&RadioAstronomy::handleFeatureRemoved
|
||||
&RadioAstronomy::handleFeatureMessageQueue
|
||||
);
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureAdded,
|
||||
QObject::disconnect(&m_availableFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&RadioAstronomy::handleFeatureAdded
|
||||
&RadioAstronomy::featuresChanged
|
||||
);
|
||||
QObject::disconnect(&m_availableRotatorHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&RadioAstronomy::rotatorsChanged
|
||||
);
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
@ -194,8 +208,6 @@ void RadioAstronomy::start()
|
||||
m_basebandSink->getInputMessageQueue()->push(new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency));
|
||||
m_basebandSink->getInputMessageQueue()->push(RadioAstronomyBaseband::MsgConfigureRadioAstronomyBaseband::create(m_settings, true));
|
||||
m_worker->getInputMessageQueue()->push(RadioAstronomyWorker::MsgConfigureRadioAstronomyWorker::create(m_settings, true));
|
||||
|
||||
scanAvailableFeatures();
|
||||
}
|
||||
|
||||
void RadioAstronomy::stop()
|
||||
@ -330,7 +342,8 @@ bool RadioAstronomy::handleMessage(const Message& cmd)
|
||||
}
|
||||
else if (MsgScanAvailableFeatures::match(cmd))
|
||||
{
|
||||
scanAvailableFeatures();
|
||||
notifyUpdateFeatures({}, {});
|
||||
notifyUpdateRotators({}, {});
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -753,22 +766,14 @@ void RadioAstronomy::applySettings(const RadioAstronomySettings& settings, bool
|
||||
{
|
||||
if (!settings.m_starTracker.isEmpty())
|
||||
{
|
||||
Feature *feature = nullptr;
|
||||
|
||||
for (const auto& fval : m_availableFeatures)
|
||||
int index = m_availableFeatures.indexOfLongId(settings.m_starTracker);
|
||||
if (index >= 0)
|
||||
{
|
||||
QString starTrackerText = tr("F%1:%2 %3").arg(fval.m_featureSetIndex).arg(fval.m_featureIndex).arg(fval.m_type);
|
||||
|
||||
if (settings.m_starTracker == starTrackerText)
|
||||
{
|
||||
feature = m_availableFeatures.key(fval);
|
||||
break;
|
||||
}
|
||||
m_selectedPipe = m_availableFeatures[index].m_object;
|
||||
}
|
||||
|
||||
if (feature) {
|
||||
m_selectedPipe = feature;
|
||||
} else {
|
||||
else
|
||||
{
|
||||
m_selectedPipe = nullptr;
|
||||
qDebug() << "RadioAstronomy::applySettings: No plugin corresponding to target " << settings.m_starTracker;
|
||||
}
|
||||
}
|
||||
@ -1246,145 +1251,39 @@ void RadioAstronomy::handleIndexInDeviceSetChanged(int index)
|
||||
m_basebandSink->setFifoLabel(fifoLabel);
|
||||
}
|
||||
|
||||
void RadioAstronomy::scanAvailableFeatures()
|
||||
void RadioAstronomy::featuresChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
qDebug("RadioAstronomy::scanAvailableFeatures");
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
MessagePipes& messagePipes = mainCore->getMessagePipes();
|
||||
std::vector<FeatureSet*>& featureSets = mainCore->getFeatureeSets();
|
||||
m_availableFeatures.clear();
|
||||
m_rotators.clear();
|
||||
|
||||
for (const auto& featureSet : featureSets)
|
||||
{
|
||||
for (int fei = 0; fei < featureSet->getNumberOfFeatures(); fei++)
|
||||
{
|
||||
Feature *feature = featureSet->getFeatureAt(fei);
|
||||
|
||||
if (RadioAstronomySettings::m_pipeURIs.contains(feature->getURI()))
|
||||
{
|
||||
if (!m_availableFeatures.contains(feature))
|
||||
{
|
||||
qDebug("RadioAstronomy::scanAvailableFeatures: register %d:%d %s (%p)",
|
||||
featureSet->getIndex(), fei, qPrintable(feature->getURI()), feature);
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(feature, this, "startracker.target");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleFeatureMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
connect(pipe, SIGNAL(toBeDeleted(int, QObject*)), this, SLOT(handleMessagePipeToBeDeleted(int, QObject*)));
|
||||
RadioAstronomySettings::AvailableFeature availableFeature =
|
||||
RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()};
|
||||
m_availableFeatures[feature] = availableFeature;
|
||||
}
|
||||
}
|
||||
else if (feature->getURI() == "sdrangel.feature.gs232controller")
|
||||
{
|
||||
RadioAstronomySettings::AvailableFeature rotator =
|
||||
RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()};
|
||||
m_rotators[feature] = rotator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notifyUpdateFeatures();
|
||||
notifyUpdateRotators();
|
||||
m_availableFeatures = m_availableFeatureHandler.getAvailableChannelOrFeatureList();
|
||||
notifyUpdateFeatures(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
void RadioAstronomy::notifyUpdateFeatures()
|
||||
|
||||
void RadioAstronomy::notifyUpdateFeatures(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create();
|
||||
msg->getFeatures() = m_availableFeatures.values();
|
||||
MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create(renameFrom, renameTo);
|
||||
msg->getFeatures() = m_availableFeatures;
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void RadioAstronomy::notifyUpdateRotators()
|
||||
void RadioAstronomy::rotatorsChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
m_rotators = m_availableRotatorHandler.getAvailableChannelOrFeatureList();
|
||||
notifyUpdateRotators(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
void RadioAstronomy::notifyUpdateRotators(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportAvailableRotators *msg = MsgReportAvailableRotators::create();
|
||||
msg->getFeatures() = m_rotators.values();
|
||||
MsgReportAvailableRotators *msg = MsgReportAvailableRotators::create(renameFrom, renameTo);
|
||||
msg->getFeatures() = m_rotators;
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void RadioAstronomy::handleFeatureAdded(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
qDebug("RadioAstronomy::handleFeatureAdded: featureSetIndex: %d:%d feature: %s (%p)",
|
||||
featureSetIndex, feature->getIndexInFeatureSet(), qPrintable(feature->getURI()), feature);
|
||||
FeatureSet *featureSet = MainCore::instance()->getFeatureeSets()[featureSetIndex];
|
||||
|
||||
if (RadioAstronomySettings::m_pipeURIs.contains(feature->getURI()))
|
||||
{
|
||||
int fei = feature->getIndexInFeatureSet();
|
||||
|
||||
if (!m_availableFeatures.contains(feature))
|
||||
{
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(feature, this, "startracker.target");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleFeatureMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
QObject::connect(
|
||||
pipe,
|
||||
&ObjectPipe::toBeDeleted,
|
||||
this,
|
||||
&RadioAstronomy::handleMessagePipeToBeDeleted
|
||||
);
|
||||
}
|
||||
|
||||
RadioAstronomySettings::AvailableFeature availableFeature =
|
||||
RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()};
|
||||
m_availableFeatures[feature] = availableFeature;
|
||||
|
||||
notifyUpdateFeatures();
|
||||
}
|
||||
else if (feature->getURI() == "sdrangel.feature.gs232controller")
|
||||
{
|
||||
if (!m_rotators.contains(feature))
|
||||
{
|
||||
RadioAstronomySettings::AvailableFeature rotator =
|
||||
RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), feature->getIndexInFeatureSet(), feature->getIdentifier()};
|
||||
m_rotators[feature] = rotator;
|
||||
}
|
||||
|
||||
notifyUpdateRotators();
|
||||
}
|
||||
}
|
||||
|
||||
void RadioAstronomy::handleFeatureRemoved(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
qDebug("RadioAstronomy::handleFeatureRemoved: featureSetIndex: %d (%p)", featureSetIndex, feature);
|
||||
|
||||
if (m_rotators.contains(feature))
|
||||
{
|
||||
m_rotators.remove(feature);
|
||||
notifyUpdateRotators();
|
||||
}
|
||||
}
|
||||
|
||||
void RadioAstronomy::handleMessagePipeToBeDeleted(int reason, QObject* object)
|
||||
{
|
||||
if ((reason == 0) && m_availableFeatures.contains((Feature*) object)) // producer (feature)
|
||||
{
|
||||
qDebug("RadioAstronomy::handleMessagePipeToBeDeleted: removing feature at (%p)", object);
|
||||
m_availableFeatures.remove((Feature*) object);
|
||||
notifyUpdateFeatures();
|
||||
}
|
||||
}
|
||||
|
||||
void RadioAstronomy::handleFeatureMessageQueue(MessageQueue* messageQueue)
|
||||
{
|
||||
Message* message;
|
||||
|
@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2021 Jon Beniston, M7RCE //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -31,6 +31,7 @@
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "util/message.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
|
||||
#include "radioastronomybaseband.h"
|
||||
#include "radioastronomysettings.h"
|
||||
@ -329,17 +330,23 @@ public:
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
QList<RadioAstronomySettings::AvailableFeature>& getFeatures() { return m_availableFeatures; }
|
||||
AvailableChannelOrFeatureList& getFeatures() { return m_availableFeatures; }
|
||||
const QStringList& getRenameFrom() const { return m_renameFrom; }
|
||||
const QStringList& getRenameTo() const { return m_renameTo; }
|
||||
|
||||
static MsgReportAvailableFeatures* create() {
|
||||
return new MsgReportAvailableFeatures();
|
||||
static MsgReportAvailableFeatures* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||
return new MsgReportAvailableFeatures(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
private:
|
||||
QList<RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
||||
AvailableChannelOrFeatureList m_availableFeatures;
|
||||
QStringList m_renameFrom;
|
||||
QStringList m_renameTo;
|
||||
|
||||
MsgReportAvailableFeatures() :
|
||||
Message()
|
||||
MsgReportAvailableFeatures(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||
Message(),
|
||||
m_renameFrom(renameFrom),
|
||||
m_renameTo(renameTo)
|
||||
{}
|
||||
};
|
||||
|
||||
@ -347,17 +354,24 @@ public:
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
QList<RadioAstronomySettings::AvailableFeature>& getFeatures() { return m_availableFeatures; }
|
||||
AvailableChannelOrFeatureList& getFeatures() { return m_availableFeatures; }
|
||||
const QStringList& getRenameFrom() const { return m_renameFrom; }
|
||||
const QStringList& getRenameTo() const { return m_renameTo; }
|
||||
|
||||
static MsgReportAvailableRotators* create() {
|
||||
return new MsgReportAvailableRotators();
|
||||
|
||||
static MsgReportAvailableRotators* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||
return new MsgReportAvailableRotators(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
private:
|
||||
QList<RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
||||
AvailableChannelOrFeatureList m_availableFeatures;
|
||||
QStringList m_renameFrom;
|
||||
QStringList m_renameTo;
|
||||
|
||||
MsgReportAvailableRotators() :
|
||||
Message()
|
||||
MsgReportAvailableRotators(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||
Message(),
|
||||
m_renameFrom(renameFrom),
|
||||
m_renameTo(renameTo)
|
||||
{}
|
||||
};
|
||||
|
||||
@ -448,8 +462,10 @@ private:
|
||||
int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
|
||||
qint64 m_centerFrequency;
|
||||
|
||||
QHash<Feature*, RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
||||
QHash<Feature*, RadioAstronomySettings::AvailableFeature> m_rotators;
|
||||
AvailableChannelOrFeatureHandler m_availableFeatureHandler;
|
||||
AvailableChannelOrFeatureList m_availableFeatures;
|
||||
AvailableChannelOrFeatureHandler m_availableRotatorHandler;
|
||||
AvailableChannelOrFeatureList m_rotators;
|
||||
QObject *m_selectedPipe;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
@ -482,9 +498,8 @@ private:
|
||||
void sweepStart();
|
||||
void startCal(bool hot);
|
||||
void calComplete(MsgCalComplete* report);
|
||||
void scanAvailableFeatures();
|
||||
void notifyUpdateFeatures();
|
||||
void notifyUpdateRotators();
|
||||
void notifyUpdateFeatures(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void notifyUpdateRotators(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
@ -496,9 +511,8 @@ private slots:
|
||||
void sweepNext();
|
||||
void sweepComplete();
|
||||
void handleIndexInDeviceSetChanged(int index);
|
||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
||||
void handleFeatureRemoved(int featureSetIndex, Feature *feature);
|
||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
||||
void featuresChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void rotatorsChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void handleFeatureMessageQueue(MessageQueue* messageQueue);
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2021 Jon Beniston, M7RCE //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -916,31 +916,33 @@ bool RadioAstronomyGUI::deserialize(const QByteArray& data)
|
||||
}
|
||||
}
|
||||
|
||||
void RadioAstronomyGUI::updateAvailableFeatures()
|
||||
void RadioAstronomyGUI::updateAvailableFeatures(const AvailableChannelOrFeatureList& availableFeatures, const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
QString currentText = ui->starTracker->currentText();
|
||||
// Update starTracker settting if it has been renamed
|
||||
if (renameFrom.contains(m_settings.m_starTracker))
|
||||
{
|
||||
m_settings.m_starTracker = renameTo[renameFrom.indexOf(m_settings.m_starTracker)];
|
||||
applySettings();
|
||||
}
|
||||
|
||||
ui->starTracker->blockSignals(true);
|
||||
ui->starTracker->clear();
|
||||
|
||||
for (const auto& feature : m_availableFeatures) {
|
||||
ui->starTracker->addItem(tr("F%1:%2 %3").arg(feature.m_featureSetIndex).arg(feature.m_featureIndex).arg(feature.m_type));
|
||||
for (const auto& feature : availableFeatures) {
|
||||
ui->starTracker->addItem(feature.getLongId());
|
||||
}
|
||||
|
||||
if (currentText.isEmpty())
|
||||
{
|
||||
if (m_availableFeatures.size() > 0) {
|
||||
ui->starTracker->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->starTracker->setCurrentIndex(ui->starTracker->findText(currentText));
|
||||
int idx = ui->starTracker->findText(m_settings.m_starTracker);
|
||||
if (idx >= 0) {
|
||||
ui->starTracker->setCurrentIndex(idx);
|
||||
} else {
|
||||
ui->starTracker->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
ui->starTracker->blockSignals(false);
|
||||
QString newText = ui->starTracker->currentText();
|
||||
|
||||
if (currentText != newText)
|
||||
QString newText = ui->starTracker->currentText();
|
||||
if (m_settings.m_starTracker != newText)
|
||||
{
|
||||
m_settings.m_starTracker = newText;
|
||||
applySettings();
|
||||
@ -970,8 +972,7 @@ bool RadioAstronomyGUI::handleMessage(const Message& message)
|
||||
{
|
||||
qDebug("RadioAstronomyGUI::handleMessage: MsgReportAvailableFeatures");
|
||||
RadioAstronomy::MsgReportAvailableFeatures& report = (RadioAstronomy::MsgReportAvailableFeatures&) message;
|
||||
m_availableFeatures = report.getFeatures();
|
||||
updateAvailableFeatures();
|
||||
updateAvailableFeatures(report.getFeatures(), report.getRenameFrom(), report.getRenameTo());
|
||||
return true;
|
||||
}
|
||||
else if (MainCore::MsgStarTrackerTarget::match(message))
|
||||
@ -1063,7 +1064,7 @@ bool RadioAstronomyGUI::handleMessage(const Message& message)
|
||||
else if (RadioAstronomy::MsgReportAvailableRotators::match(message))
|
||||
{
|
||||
RadioAstronomy::MsgReportAvailableRotators& report = (RadioAstronomy::MsgReportAvailableRotators&) message;
|
||||
updateRotatorList(report.getFeatures());
|
||||
updateRotatorList(report.getFeatures(), report.getRenameFrom(), report.getRenameTo());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1901,11 +1902,11 @@ void RadioAstronomyGUI::on_loadSpectrumData_clicked()
|
||||
|
||||
void RadioAstronomyGUI::on_powerTable_cellDoubleClicked(int row, int column)
|
||||
{
|
||||
if ((column >= POWER_COL_RA) && (column >= POWER_COL_EL))
|
||||
if ((column >= POWER_COL_RA) && (column <= POWER_COL_EL))
|
||||
{
|
||||
// Display target in Star Tracker
|
||||
QList<ObjectPipe*> starTrackerPipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(this, "startracker.display", starTrackerPipes);
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(m_radioAstronomy, "startracker.display", starTrackerPipes);
|
||||
|
||||
for (const auto& pipe : starTrackerPipes)
|
||||
{
|
||||
@ -2604,17 +2605,22 @@ void RadioAstronomyGUI::tick()
|
||||
m_tickCount++;
|
||||
}
|
||||
|
||||
void RadioAstronomyGUI::updateRotatorList(const QList<RadioAstronomySettings::AvailableFeature>& rotators)
|
||||
void RadioAstronomyGUI::updateRotatorList(const AvailableChannelOrFeatureList& rotators, const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
// Update rotator settting if it has been renamed
|
||||
if (renameFrom.contains(m_settings.m_rotator))
|
||||
{
|
||||
m_settings.m_rotator = renameTo[renameFrom.indexOf(m_settings.m_rotator)];
|
||||
applySettings();
|
||||
}
|
||||
|
||||
// Update list of rotators
|
||||
ui->rotator->blockSignals(true);
|
||||
ui->rotator->clear();
|
||||
ui->rotator->addItem("None");
|
||||
|
||||
for (const auto& rotator : rotators)
|
||||
{
|
||||
QString name = QString("F%1:%2 %3").arg(rotator.m_featureSetIndex).arg(rotator.m_featureIndex).arg(rotator.m_type);
|
||||
ui->rotator->addItem(name);
|
||||
for (const auto& rotator : rotators) {
|
||||
ui->rotator->addItem(rotator.getLongId());
|
||||
}
|
||||
|
||||
// Rotator feature can be created after this plugin, so select it
|
||||
@ -4335,7 +4341,7 @@ void RadioAstronomyGUI::updateLoSMarker(const QString& name, float l, float b, f
|
||||
{
|
||||
// Send to Star Tracker
|
||||
QList<ObjectPipe*> starTrackerPipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(this, "startracker.display", starTrackerPipes);
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(m_radioAstronomy, "startracker.display", starTrackerPipes);
|
||||
|
||||
for (const auto& pipe : starTrackerPipes)
|
||||
{
|
||||
@ -4794,7 +4800,7 @@ void RadioAstronomyGUI::on_spectrumIndex_valueChanged(int value)
|
||||
|
||||
// Display target in Star Tracker
|
||||
QList<ObjectPipe*> starTrackerPipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(this, "startracker.display", starTrackerPipes);
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(m_radioAstronomy, "startracker.display", starTrackerPipes);
|
||||
|
||||
for (const auto& pipe : starTrackerPipes)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2021 Jon Beniston, M7RCE //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -235,7 +235,6 @@ private:
|
||||
RollupState m_rollupState;
|
||||
RadioAstronomySettings m_settings;
|
||||
bool m_doApplySettings;
|
||||
QList<RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
||||
|
||||
int m_basebandSampleRate;
|
||||
quint64 m_centerFrequency;
|
||||
@ -351,8 +350,8 @@ private:
|
||||
void displaySettings();
|
||||
void displaySpectrumLineFrequency();
|
||||
void displayRunModeSettings();
|
||||
void updateAvailableFeatures();
|
||||
void updateRotatorList(const QList<RadioAstronomySettings::AvailableFeature>& rotators);
|
||||
void updateAvailableFeatures(const AvailableChannelOrFeatureList& availableFeatures, const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void updateRotatorList(const AvailableChannelOrFeatureList& rotators, const QStringList& renameFrom, const QStringList& renameTo);
|
||||
bool handleMessage(const Message& message);
|
||||
void makeUIConnections();
|
||||
void updateAbsoluteCenterFrequency();
|
||||
|
@ -23,14 +23,6 @@
|
||||
#include "settings/serializable.h"
|
||||
#include "radioastronomysettings.h"
|
||||
|
||||
const QStringList RadioAstronomySettings::m_pipeTypes = {
|
||||
QStringLiteral("StarTracker")
|
||||
};
|
||||
|
||||
const QStringList RadioAstronomySettings::m_pipeURIs = {
|
||||
QStringLiteral("sdrangel.feature.startracker")
|
||||
};
|
||||
|
||||
RadioAstronomySettings::RadioAstronomySettings() :
|
||||
m_channelMarker(nullptr),
|
||||
m_rollupState(nullptr)
|
||||
|
@ -35,20 +35,6 @@ class Serializable;
|
||||
|
||||
struct RadioAstronomySettings
|
||||
{
|
||||
struct AvailableFeature
|
||||
{
|
||||
int m_featureSetIndex;
|
||||
int m_featureIndex;
|
||||
QString m_type;
|
||||
|
||||
AvailableFeature() = default;
|
||||
AvailableFeature(const AvailableFeature&) = default;
|
||||
AvailableFeature& operator=(const AvailableFeature&) = default;
|
||||
bool operator==(const AvailableFeature& a) const {
|
||||
return (m_featureSetIndex == a.m_featureSetIndex) && (m_featureIndex == a.m_featureIndex) && (m_type == a.m_type);
|
||||
}
|
||||
};
|
||||
|
||||
int m_inputFrequencyOffset;
|
||||
int m_sampleRate;
|
||||
int m_rfBandwidth;
|
||||
@ -244,9 +230,6 @@ struct RadioAstronomySettings
|
||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
|
||||
static const QStringList m_pipeTypes;
|
||||
static const QStringList m_pipeURIs;
|
||||
};
|
||||
|
||||
#endif /* INCLUDE_RADIOASTRONOMYSETTINGS_H */
|
||||
|
@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2021 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -41,7 +41,8 @@ const char* const AIS::m_featureIdURI = "sdrangel.feature.ais";
|
||||
const char* const AIS::m_featureId = "AIS";
|
||||
|
||||
AIS::AIS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface)
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_availableChannelHandler({"sdrangel.channel.aisdemod"}, QStringList{"ais"})
|
||||
{
|
||||
qDebug("AIS::AIS: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||
setObjectName(m_featureId);
|
||||
@ -54,23 +55,20 @@ AIS::AIS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
this,
|
||||
&AIS::networkManagerFinished
|
||||
);
|
||||
scanAvailableChannels();
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&AIS::handleChannelAdded
|
||||
);
|
||||
&AIS::handleChannelMessageQueue);
|
||||
}
|
||||
|
||||
AIS::~AIS()
|
||||
{
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&AIS::handleChannelAdded
|
||||
);
|
||||
&AIS::handleChannelMessageQueue);
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
@ -362,90 +360,6 @@ void AIS::networkManagerFinished(QNetworkReply *reply)
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void AIS::scanAvailableChannels()
|
||||
{
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
MessagePipes& messagePipes = mainCore->getMessagePipes();
|
||||
std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets();
|
||||
m_availableChannels.clear();
|
||||
|
||||
for (const auto& deviceSet : deviceSets)
|
||||
{
|
||||
DSPDeviceSourceEngine *deviceSourceEngine = deviceSet->m_deviceSourceEngine;
|
||||
|
||||
if (deviceSourceEngine)
|
||||
{
|
||||
for (int chi = 0; chi < deviceSet->getNumberOfChannels(); chi++)
|
||||
{
|
||||
ChannelAPI *channel = deviceSet->getChannelAt(chi);
|
||||
|
||||
if ((channel->getURI() == "sdrangel.channel.aisdemod") && !m_availableChannels.contains(channel))
|
||||
{
|
||||
qDebug("AIS::scanAvailableChannels: register %d:%d (%p)", deviceSet->getIndex(), chi, channel);
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(channel, this, "ais");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleChannelMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
QObject::connect(
|
||||
pipe,
|
||||
&ObjectPipe::toBeDeleted,
|
||||
this,
|
||||
&AIS::handleMessagePipeToBeDeleted
|
||||
);
|
||||
m_availableChannels.insert(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AIS::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
qDebug("AIS::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)",
|
||||
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
||||
std::vector<DeviceSet*>& deviceSets = MainCore::instance()->getDeviceSets();
|
||||
DeviceSet *deviceSet = deviceSets[deviceSetIndex];
|
||||
DSPDeviceSourceEngine *deviceSourceEngine = deviceSet->m_deviceSourceEngine;
|
||||
|
||||
if (deviceSourceEngine && (channel->getURI() == "sdrangel.channel.aisdemod"))
|
||||
{
|
||||
if (!m_availableChannels.contains(channel))
|
||||
{
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(channel, this, "ais");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleChannelMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
QObject::connect(
|
||||
pipe,
|
||||
&ObjectPipe::toBeDeleted,
|
||||
this,
|
||||
&AIS::handleMessagePipeToBeDeleted
|
||||
);
|
||||
m_availableChannels.insert(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AIS::handleMessagePipeToBeDeleted(int reason, QObject* object)
|
||||
{
|
||||
if ((reason == 0) && m_availableChannels.contains((ChannelAPI*) object)) // producer (channel)
|
||||
{
|
||||
qDebug("AIS::handleMessagePipeToBeDeleted: removing channel at (%p)", object);
|
||||
m_availableChannels.remove((ChannelAPI*) object);
|
||||
}
|
||||
}
|
||||
|
||||
void AIS::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||
{
|
||||
Message* message;
|
||||
|
@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||
// Copyright (C) 2021-2022 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include "feature/feature.h"
|
||||
#include "util/message.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
|
||||
#include "aissettings.h"
|
||||
|
||||
@ -101,7 +102,8 @@ public:
|
||||
|
||||
private:
|
||||
AISSettings m_settings;
|
||||
QSet<ChannelAPI*> m_availableChannels;
|
||||
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
@ -110,12 +112,9 @@ private:
|
||||
void stop();
|
||||
void applySettings(const AISSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const AISSettings& settings, bool force);
|
||||
void scanAvailableChannels();
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -47,7 +47,7 @@ QStringList AISGUI::m_shipModels = {
|
||||
"tug_20m.glbe", "tug_30m_1.glbe", "tug_30m_2.glbe", "tug_30m_3.glbe",
|
||||
"cargo_75m.glbe", "tanker_50m.glbe", "dredger_53m.glbe",
|
||||
"trawler_22m.glbe",
|
||||
"speedboat_8m.glbe", "yacht_10m.glbe", "yacht_20m.glbe", "yacht_42m.glbe"
|
||||
"speedboat_8m.glbe", /*"yacht_10m.glbe",*/ "yacht_20m.glbe", "yacht_42m.glbe"
|
||||
};
|
||||
|
||||
QStringList AISGUI::m_sailboatModels = {
|
||||
@ -236,6 +236,7 @@ AISGUI::AISGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
|
||||
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
m_resizer.enableChildMouseTracking();
|
||||
}
|
||||
|
||||
AISGUI::~AISGUI()
|
||||
@ -845,14 +846,14 @@ void AISGUI::getImageAndModel(const QString &type, const QString &shipType, int
|
||||
{
|
||||
vessel->m_model = "cargo_75m.glbe";
|
||||
}
|
||||
else if (length < 200)
|
||||
else /*if (length < 200)*/
|
||||
{
|
||||
vessel->m_model = "cargo_190m.glbe";
|
||||
}
|
||||
else
|
||||
/*else
|
||||
{
|
||||
vessel->m_model = "cargo_230m.glbe";
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else if (shipType == "Tanker")
|
||||
{
|
||||
@ -905,10 +906,10 @@ void AISGUI::getImageAndModel(const QString &type, const QString &shipType, int
|
||||
{
|
||||
vessel->m_model = "speedboat_8m.glbe";
|
||||
}
|
||||
else if (length < 18)
|
||||
/*else if (length < 18)
|
||||
{
|
||||
vessel->m_model = "yacht_10m.glbe";
|
||||
}
|
||||
}*/
|
||||
else if (length < 32)
|
||||
{
|
||||
vessel->m_model = "yacht_20m.glbe";
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -46,7 +46,8 @@ const char* const APRS::m_featureId = "APRS";
|
||||
APRS::APRS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_thread(nullptr),
|
||||
m_worker(nullptr)
|
||||
m_worker(nullptr),
|
||||
m_availableChannelHandler(APRSSettings::m_pipeURIs, QStringList{"packets"})
|
||||
{
|
||||
qDebug("APRS::APRS: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||
setObjectName(m_featureId);
|
||||
@ -59,23 +60,31 @@ APRS::APRS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
this,
|
||||
&APRS::networkManagerFinished
|
||||
);
|
||||
scanAvailableChannels();
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&APRS::handleChannelAdded
|
||||
);
|
||||
&APRS::handleChannelMessageQueue);
|
||||
QObject::connect(
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&APRS::channelsChanged);
|
||||
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
APRS::~APRS()
|
||||
{
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&APRS::handleChannelAdded
|
||||
);
|
||||
&APRS::handleChannelMessageQueue);
|
||||
QObject::disconnect(
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&APRS::channelsChanged);
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
@ -858,6 +867,7 @@ void APRS::networkManagerFinished(QNetworkReply *reply)
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
/*
|
||||
void APRS::scanAvailableChannels()
|
||||
{
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
@ -905,18 +915,25 @@ void APRS::scanAvailableChannels()
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void APRS::channelsChanged()
|
||||
{
|
||||
m_availableChannels = m_availableChannelHandler.getAvailableChannelOrFeatureList();
|
||||
notifyUpdateChannels();
|
||||
}
|
||||
|
||||
void APRS::notifyUpdateChannels()
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportAvailableChannels *msg = MsgReportAvailableChannels::create();
|
||||
msg->getChannels() = m_availableChannels.values();
|
||||
msg->getChannels() = m_availableChannels;
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void APRS::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
/*void APRS::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
qDebug("APRS::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)",
|
||||
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
||||
@ -964,7 +981,7 @@ void APRS::handleMessagePipeToBeDeleted(int reason, QObject* object)
|
||||
m_availableChannels.remove((ChannelAPI*) object);
|
||||
notifyUpdateChannels();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void APRS::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||
// Copyright (C) 2021-2022 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
#include "feature/feature.h"
|
||||
#include "util/message.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
|
||||
#include "aprssettings.h"
|
||||
|
||||
@ -104,14 +105,14 @@ public:
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
QList<APRSSettings::AvailableChannel>& getChannels() { return m_availableChannels; }
|
||||
AvailableChannelOrFeatureList& getChannels() { return m_availableChannels; }
|
||||
|
||||
static MsgReportAvailableChannels* create() {
|
||||
return new MsgReportAvailableChannels();
|
||||
}
|
||||
|
||||
private:
|
||||
QList<APRSSettings::AvailableChannel> m_availableChannels;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
|
||||
MsgReportAvailableChannels() :
|
||||
Message()
|
||||
@ -160,7 +161,8 @@ private:
|
||||
QThread *m_thread;
|
||||
APRSWorker *m_worker;
|
||||
APRSSettings m_settings;
|
||||
QHash<ChannelAPI*, APRSSettings::AvailableChannel> m_availableChannels;
|
||||
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
@ -169,14 +171,12 @@ private:
|
||||
void stop();
|
||||
void applySettings(const APRSSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const APRSSettings& settings, bool force);
|
||||
void scanAvailableChannels();
|
||||
void notifyUpdateChannels();
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
||||
void channelsChanged();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_APRS_H_
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -708,7 +708,7 @@ void APRSGUI::updateChannelList()
|
||||
ui->sourcePipes->clear();
|
||||
|
||||
for (const auto& channel : m_availableChannels) {
|
||||
ui->sourcePipes->addItem(tr("R%1:%2 %3").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex).arg(channel.m_type));
|
||||
ui->sourcePipes->addItem(channel.getLongId());
|
||||
}
|
||||
|
||||
ui->sourcePipes->blockSignals(false);
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -30,6 +30,7 @@
|
||||
#include "util/messagequeue.h"
|
||||
#include "util/aprs.h"
|
||||
#include "settings/rollupstate.h"
|
||||
#include "availablechannelorfeature.h"
|
||||
|
||||
#include "aprssettings.h"
|
||||
|
||||
@ -123,7 +124,7 @@ private:
|
||||
QList<QString> m_settingsKeys;
|
||||
RollupState m_rollupState;
|
||||
bool m_doApplySettings;
|
||||
QList<APRSSettings::AvailableChannel> m_availableChannels;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
|
||||
APRS* m_aprs;
|
||||
MessageQueue m_inputMessageQueue;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// Copyright (C) 2015-2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020-2021 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -38,17 +38,6 @@ class Serializable;
|
||||
|
||||
struct APRSSettings
|
||||
{
|
||||
struct AvailableChannel
|
||||
{
|
||||
int m_deviceSetIndex;
|
||||
int m_channelIndex;
|
||||
QString m_type;
|
||||
|
||||
AvailableChannel() = default;
|
||||
AvailableChannel(const AvailableChannel&) = default;
|
||||
AvailableChannel& operator=(const AvailableChannel&) = default;
|
||||
};
|
||||
|
||||
QString m_igateServer;
|
||||
int m_igatePort;
|
||||
QString m_igateCallsign;
|
||||
|
@ -48,4 +48,4 @@ APRS icons are from: https://github.com/hessu/aprs-symbols
|
||||
|
||||
Full details of the API can be found in the Swagger documentation. Here is a quick example of how to enable the APRS-IS IGate:
|
||||
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "APRS", "APRSSettings": { "igateCallsign": "MYCALLSIGN", "igatePasscode": "12345", "igateFilter": "r/50.2/10.2/25", "igateEnabled": 1 }}'
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "APRS", "APRSSettings": { "igateCallsign": "MYCALLSIGN", "igatePasscode": "12345", "igateFilter": "r/50.2/10.2/25", "igateEnabled": 1 }}'
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||
// //
|
||||
@ -56,6 +56,8 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface)
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_thread(nullptr),
|
||||
m_worker(nullptr),
|
||||
m_availableChannelOrFeatureHandler(GS232ControllerSettings::m_pipeURIs),
|
||||
m_selectedPipe(nullptr),
|
||||
m_currentAzimuth(0.0f),
|
||||
m_currentElevation(0.0f)
|
||||
{
|
||||
@ -63,7 +65,6 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface)
|
||||
setObjectName(m_featureId);
|
||||
m_state = StIdle;
|
||||
m_errorMessage = "GS232Controller error";
|
||||
m_selectedPipe = nullptr;
|
||||
m_networkManager = new QNetworkAccessManager();
|
||||
QObject::connect(
|
||||
m_networkManager,
|
||||
@ -71,30 +72,21 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface)
|
||||
this,
|
||||
&GS232Controller::networkManagerFinished
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureAdded,
|
||||
&m_availableChannelOrFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&GS232Controller::handleFeatureAdded
|
||||
&GS232Controller::channelsOrFeaturesChanged
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
&m_availableChannelOrFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&GS232Controller::handleChannelAdded
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureRemoved,
|
||||
this,
|
||||
&GS232Controller::handleFeatureRemoved
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelRemoved,
|
||||
this,
|
||||
&GS232Controller::handleChannelRemoved
|
||||
&GS232Controller::handlePipeMessageQueue
|
||||
);
|
||||
m_availableChannelOrFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||
|
||||
connect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts);
|
||||
m_timer.start(5000);
|
||||
}
|
||||
@ -104,28 +96,16 @@ GS232Controller::~GS232Controller()
|
||||
m_timer.stop();
|
||||
disconnect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts);
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelRemoved,
|
||||
&m_availableChannelOrFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||
this,
|
||||
&GS232Controller::handleChannelRemoved
|
||||
&GS232Controller::channelsOrFeaturesChanged
|
||||
);
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureRemoved,
|
||||
&m_availableChannelOrFeatureHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&GS232Controller::handleFeatureRemoved
|
||||
);
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
this,
|
||||
&GS232Controller::handleChannelAdded
|
||||
);
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureAdded,
|
||||
this,
|
||||
&GS232Controller::handleFeatureAdded
|
||||
&GS232Controller::handlePipeMessageQueue
|
||||
);
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
@ -154,8 +134,6 @@ void GS232Controller::start()
|
||||
GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg =
|
||||
GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(m_settings, QList<QString>(), true);
|
||||
m_worker->getInputMessageQueue()->push(msg);
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void GS232Controller::stop()
|
||||
@ -210,7 +188,7 @@ bool GS232Controller::handleMessage(const Message& cmd)
|
||||
}
|
||||
else if (MsgScanAvailableChannelOrFeatures::match(cmd))
|
||||
{
|
||||
scanAvailableChannelsAndFeatures();
|
||||
notifyUpdate({}, {});
|
||||
return true;
|
||||
}
|
||||
else if (GS232ControllerReport::MsgReportAzAl::match(cmd))
|
||||
@ -248,8 +226,6 @@ bool GS232Controller::handleMessage(const Message& cmd)
|
||||
applySettings(m_settings, QList<QString>{"azimuth", "elevation"});
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug() << "GS232Controller::handleMessage: No match " << msg.getPipeSource() << " " << m_selectedPipe;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -306,10 +282,6 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con
|
||||
{
|
||||
qDebug() << "GS232Controller::applySettings:" << settings.getDebugString(settingsKeys, force) << " force: " << force;
|
||||
|
||||
// if ((m_settings.m_source != settings.m_source)
|
||||
// || (!settings.m_source.isEmpty() && (m_selectedPipe == nullptr)) // Change in available pipes
|
||||
// || force)
|
||||
|
||||
if (settingsKeys.contains("source")
|
||||
|| (!settings.m_source.isEmpty() && (m_selectedPipe == nullptr)) // Change in available pipes
|
||||
|| force)
|
||||
@ -317,27 +289,24 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
MessagePipes& messagePipes = mainCore->getMessagePipes();
|
||||
|
||||
if (m_selectedPipe)
|
||||
m_availableChannelOrFeatureHandler.deregisterPipes(m_selectedPipe, this, {"target"});
|
||||
|
||||
/*if (m_selectedPipe)
|
||||
{
|
||||
qDebug("GS232Controller::applySettings: unregister %s (%p)", qPrintable(m_selectedPipe->objectName()), m_selectedPipe);
|
||||
// Don't deref m_selectedPipe, as plugin may have been deleted
|
||||
qDebug("GS232Controller::applySettings: unregister (%p)", m_selectedPipe);
|
||||
messagePipes.unregisterProducerToConsumer(m_selectedPipe, this, "target");
|
||||
}
|
||||
}*/
|
||||
|
||||
if (!settings.m_source.isEmpty())
|
||||
m_selectedPipe = m_availableChannelOrFeatureHandler.registerPipes(settings.m_source, this, {"target"});
|
||||
|
||||
/*if (!settings.m_source.isEmpty())
|
||||
{
|
||||
QObject *object = nullptr;
|
||||
int index = m_availableChannelOrFeatures.indexOfLongId(settings.m_source);
|
||||
|
||||
for (const auto& oval : m_availableChannelOrFeatures)
|
||||
{
|
||||
if (settings.m_source == oval.getLongId())
|
||||
{
|
||||
object = oval.m_object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (object)
|
||||
if (index >= 0)
|
||||
{
|
||||
QObject *object = m_availableChannelOrFeatures[index].m_object;
|
||||
registerPipe(object);
|
||||
m_selectedPipe = object;
|
||||
}
|
||||
@ -350,7 +319,7 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con
|
||||
else
|
||||
{
|
||||
m_selectedPipe = nullptr;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg = GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(
|
||||
@ -718,12 +687,7 @@ void GS232Controller::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& r
|
||||
|
||||
for (const auto& item : m_availableChannelOrFeatures)
|
||||
{
|
||||
QString itemText = tr("%1%2:%3 %4")
|
||||
.arg(item.m_kind)
|
||||
.arg(item.m_superIndex)
|
||||
.arg(item.m_index)
|
||||
.arg(item.m_type);
|
||||
|
||||
QString itemText = item.getLongId();
|
||||
response.getGs232ControllerReport()->getSources()->append(new QString(itemText));
|
||||
}
|
||||
|
||||
@ -763,69 +727,22 @@ void GS232Controller::networkManagerFinished(QNetworkReply *reply)
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void GS232Controller::scanAvailableChannelsAndFeatures()
|
||||
void GS232Controller::channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
m_availableChannelOrFeatures = MainCore::instance()->getAvailableChannelsAndFeatures(GS232ControllerSettings::m_pipeURIs);
|
||||
notifyUpdate();
|
||||
m_availableChannelOrFeatures = m_availableChannelOrFeatureHandler.getAvailableChannelOrFeatureList();
|
||||
notifyUpdate(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
void GS232Controller::notifyUpdate()
|
||||
void GS232Controller::notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportAvailableChannelOrFeatures *msg = MsgReportAvailableChannelOrFeatures::create();
|
||||
MsgReportAvailableChannelOrFeatures *msg = MsgReportAvailableChannelOrFeatures::create(renameFrom, renameTo);
|
||||
msg->getItems() = m_availableChannelOrFeatures;
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void GS232Controller::handleFeatureAdded(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) feature;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void GS232Controller::handleFeatureRemoved(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) feature;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void GS232Controller::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
(void) deviceSetIndex;
|
||||
(void) channel;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void GS232Controller::handleChannelRemoved(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
(void) deviceSetIndex;
|
||||
(void) channel;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void GS232Controller::registerPipe(QObject *object)
|
||||
{
|
||||
qDebug("GS232Controller::registerPipe: register %s (%p)", qPrintable(object->objectName()), object);
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(object, this, "target");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handlePipeMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
|
||||
void GS232Controller::handlePipeMessageQueue(MessageQueue* messageQueue)
|
||||
{
|
||||
Message* message;
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||
// //
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#include "feature/feature.h"
|
||||
#include "util/message.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "gs232controllersettings.h"
|
||||
@ -111,17 +112,23 @@ public:
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
QList<MainCore::AvailableChannelOrFeature>& getItems() { return m_availableChannelOrFeatures; }
|
||||
AvailableChannelOrFeatureList& getItems() { return m_availableChannelOrFeatures; }
|
||||
const QStringList& getRenameFrom() const { return m_renameFrom; }
|
||||
const QStringList& getRenameTo() const { return m_renameTo; }
|
||||
|
||||
static MsgReportAvailableChannelOrFeatures* create() {
|
||||
return new MsgReportAvailableChannelOrFeatures();
|
||||
static MsgReportAvailableChannelOrFeatures* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||
return new MsgReportAvailableChannelOrFeatures(renameFrom, renameTo);
|
||||
}
|
||||
|
||||
private:
|
||||
QList<MainCore::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
||||
AvailableChannelOrFeatureList m_availableChannelOrFeatures;
|
||||
QStringList m_renameFrom;
|
||||
QStringList m_renameTo;
|
||||
|
||||
MsgReportAvailableChannelOrFeatures() :
|
||||
Message()
|
||||
MsgReportAvailableChannelOrFeatures(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||
Message(),
|
||||
m_renameFrom(renameFrom),
|
||||
m_renameTo(renameTo)
|
||||
{}
|
||||
};
|
||||
|
||||
@ -213,8 +220,8 @@ private:
|
||||
QThread *m_thread;
|
||||
GS232ControllerWorker *m_worker;
|
||||
GS232ControllerSettings m_settings;
|
||||
//QHash<QObject*, GS232ControllerSettings::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
||||
QList<MainCore::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
||||
AvailableChannelOrFeatureList m_availableChannelOrFeatures;
|
||||
AvailableChannelOrFeatureHandler m_availableChannelOrFeatureHandler;
|
||||
QObject *m_selectedPipe;
|
||||
|
||||
QTimer m_timer;
|
||||
@ -231,17 +238,11 @@ private:
|
||||
void applySettings(const GS232ControllerSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const GS232ControllerSettings& settings, bool force);
|
||||
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
|
||||
void scanAvailableChannelsAndFeatures();
|
||||
void notifyUpdate();
|
||||
void registerPipe(QObject *object);
|
||||
void notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleFeatureRemoved(int featureSetIndex, Feature *feature);
|
||||
void handleChannelRemoved(int deviceSetIndex, ChannelAPI *feature);
|
||||
//void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
||||
void channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void handlePipeMessageQueue(MessageQueue* messageQueue);
|
||||
void scanSerialPorts();
|
||||
};
|
||||
|
@ -51,7 +51,7 @@ void GS232ControllerGUI::resetToDefaults()
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
applyAllSettings();
|
||||
}
|
||||
|
||||
QByteArray GS232ControllerGUI::serialize() const
|
||||
@ -65,7 +65,7 @@ bool GS232ControllerGUI::deserialize(const QByteArray& data)
|
||||
{
|
||||
m_feature->setWorkspaceIndex(m_settings.m_workspaceIndex);
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
applyAllSettings();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -121,9 +121,7 @@ void GS232ControllerGUI::displayToAzEl(float coord1, float coord2)
|
||||
m_settings.m_azimuth = coord1;
|
||||
m_settings.m_elevation = coord2;
|
||||
}
|
||||
m_settingsKeys.append("azimuth");
|
||||
m_settingsKeys.append("elevation");
|
||||
applySettings();
|
||||
applySettings({"azimuth", "elevation"});
|
||||
}
|
||||
|
||||
bool GS232ControllerGUI::handleMessage(const Message& message)
|
||||
@ -149,7 +147,7 @@ bool GS232ControllerGUI::handleMessage(const Message& message)
|
||||
{
|
||||
GS232Controller::MsgReportAvailableChannelOrFeatures& report =
|
||||
(GS232Controller::MsgReportAvailableChannelOrFeatures&) message;
|
||||
updatePipeList(report.getItems());
|
||||
updatePipeList(report.getItems(), report.getRenameFrom(), report.getRenameTo());
|
||||
return true;
|
||||
}
|
||||
else if (GS232ControllerReport::MsgReportAzAl::match(message))
|
||||
@ -206,7 +204,7 @@ void GS232ControllerGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||
(void) rollDown;
|
||||
|
||||
getRollupContents()->saveState(m_rollupState);
|
||||
applySettings();
|
||||
applySetting("rollupState");
|
||||
}
|
||||
|
||||
GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
|
||||
@ -260,7 +258,7 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu
|
||||
connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController);
|
||||
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
applyAllSettings();
|
||||
makeUIConnections();
|
||||
|
||||
// Get pre-existing pipes
|
||||
@ -408,8 +406,7 @@ void GS232ControllerGUI::on_inputController_currentIndexChanged(int index)
|
||||
if (index >= 0)
|
||||
{
|
||||
m_settings.m_inputController = ui->inputController->currentText();
|
||||
m_settingsKeys.append("inputController");
|
||||
applySettings();
|
||||
applySetting("inputController");
|
||||
updateInputController();
|
||||
}
|
||||
}
|
||||
@ -425,28 +422,24 @@ void GS232ControllerGUI::on_highSensitivity_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_highSensitivity = checked;
|
||||
ui->highSensitivity->setText(checked ? "H" : "L");
|
||||
m_settingsKeys.append("highSensitivity");
|
||||
applySettings();
|
||||
applySetting("highSensitivity");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_enableTargetControl_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_targetControlEnabled = checked;
|
||||
m_settingsKeys.append("targetControlEnabled");
|
||||
applySettings();
|
||||
applySetting("targetControlEnabled");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_enableOffsetControl_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_offsetControlEnabled = checked;
|
||||
m_settingsKeys.append("offsetControlEnabled");
|
||||
applySettings();
|
||||
applySetting("offsetControlEnabled");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::inputConfigurationComplete()
|
||||
{
|
||||
m_settingsKeys.append("inputControllerSettings");
|
||||
applySettings();
|
||||
applySetting("inputControllerSettings");
|
||||
}
|
||||
|
||||
GS232ControllerGUI::~GS232ControllerGUI()
|
||||
@ -546,10 +539,16 @@ void GS232ControllerGUI::updateSerialPortList(const QStringList& serialPorts)
|
||||
ui->serialPort->blockSignals(false);
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::updatePipeList(const QList<MainCore::AvailableChannelOrFeature>& sources)
|
||||
void GS232ControllerGUI::updatePipeList(const AvailableChannelOrFeatureList& sources, const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
QString currentText = ui->sources->currentText();
|
||||
QString newText;
|
||||
// Update source settting if it has been renamed
|
||||
if (renameFrom.contains(m_settings.m_source))
|
||||
{
|
||||
m_settings.m_source = renameTo[renameFrom.indexOf(m_settings.m_source)];
|
||||
applySetting("source");
|
||||
}
|
||||
|
||||
int prevIdx = ui->sources->currentIndex();
|
||||
ui->sources->blockSignals(true);
|
||||
ui->sources->clear();
|
||||
|
||||
@ -557,40 +556,33 @@ void GS232ControllerGUI::updatePipeList(const QList<MainCore::AvailableChannelOr
|
||||
ui->sources->addItem(source.getLongId());
|
||||
}
|
||||
|
||||
int index = ui->sources->findText(m_settings.m_source);
|
||||
ui->sources->setCurrentIndex(index);
|
||||
|
||||
if (index < 0) // current source is not found
|
||||
// Select current setting, if it exists
|
||||
// If not, and no prior setting, make sure nothing selected, as channel/feature may be created later on
|
||||
// If not found and something was previously selected, clear the setting, as probably deleted
|
||||
int idx = ui->sources->findText(m_settings.m_source);
|
||||
if (idx >= 0)
|
||||
{
|
||||
ui->sources->setCurrentIndex(idx);
|
||||
}
|
||||
else if (prevIdx == -1)
|
||||
{
|
||||
ui->sources->setCurrentIndex(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.m_source = "";
|
||||
applySetting("source");
|
||||
ui->targetName->setText("");
|
||||
m_settingsKeys.append("source");
|
||||
applySettings();
|
||||
}
|
||||
|
||||
// if (currentText.isEmpty())
|
||||
// {
|
||||
// // Source feature may be loaded after this, so may not have existed when
|
||||
// // displaySettings was called
|
||||
// if (sources.size() > 0) {
|
||||
// ui->sources->setCurrentIndex(ui->sources->findText(m_settings.m_source));
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ui->sources->setCurrentIndex(ui->sources->findText(currentText));
|
||||
// }
|
||||
|
||||
ui->sources->blockSignals(false);
|
||||
|
||||
// QString newText = ui->sources->currentText();
|
||||
|
||||
// if (currentText != newText)
|
||||
// {
|
||||
// m_settings.m_source = newText;
|
||||
// ui->targetName->setText("");
|
||||
// applySettings();
|
||||
// }
|
||||
// If no current settting, select first available
|
||||
if (m_settings.m_source.isEmpty() && (ui->sources->count() > 0))
|
||||
{
|
||||
ui->sources->setCurrentIndex(0);
|
||||
on_sources_currentTextChanged(ui->sources->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::onMenuDialogCalled(const QPoint &p)
|
||||
@ -620,15 +612,17 @@ void GS232ControllerGUI::onMenuDialogCalled(const QPoint &p)
|
||||
setTitle(m_settings.m_title);
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
|
||||
m_settingsKeys.append("title");
|
||||
m_settingsKeys.append("rgbColor");
|
||||
m_settingsKeys.append("useReverseAPI");
|
||||
m_settingsKeys.append("reverseAPIAddress");
|
||||
m_settingsKeys.append("reverseAPIPort");
|
||||
m_settingsKeys.append("reverseAPIFeatureSetIndex");
|
||||
m_settingsKeys.append("reverseAPIFeatureIndex");
|
||||
QList<QString> settingsKeys({
|
||||
"rgbColor",
|
||||
"title",
|
||||
"useReverseAPI",
|
||||
"reverseAPIAddress",
|
||||
"reverseAPIPort",
|
||||
"reverseAPIDeviceIndex",
|
||||
"reverseAPIChannelIndex"
|
||||
});
|
||||
|
||||
applySettings();
|
||||
applySettings(settingsKeys);
|
||||
}
|
||||
|
||||
resetContextMenuType();
|
||||
@ -698,15 +692,13 @@ void GS232ControllerGUI::on_protocol_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_protocol = (GS232ControllerSettings::Protocol)index;
|
||||
setProtocol(m_settings.m_protocol);
|
||||
m_settingsKeys.append("protocol");
|
||||
applySettings();
|
||||
applySetting("protocol");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_connection_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_connection = (GS232ControllerSettings::Connection)index;
|
||||
m_settingsKeys.append("connection");
|
||||
applySettings();
|
||||
applySetting("connection");
|
||||
updateConnectionWidgets();
|
||||
}
|
||||
|
||||
@ -714,30 +706,26 @@ void GS232ControllerGUI::on_serialPort_currentIndexChanged(int index)
|
||||
{
|
||||
(void) index;
|
||||
m_settings.m_serialPort = ui->serialPort->currentText();
|
||||
m_settingsKeys.append("serialPort");
|
||||
applySettings();
|
||||
applySetting("serialPort");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_baudRate_currentIndexChanged(int index)
|
||||
{
|
||||
(void) index;
|
||||
m_settings.m_baudRate = ui->baudRate->currentText().toInt();
|
||||
m_settingsKeys.append("baudRate");
|
||||
applySettings();
|
||||
applySetting("baudRate");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_host_editingFinished()
|
||||
{
|
||||
m_settings.m_host = ui->host->text();
|
||||
m_settingsKeys.append("host");
|
||||
applySettings();
|
||||
applySetting("host");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_port_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_port = value;
|
||||
m_settingsKeys.append("port");
|
||||
applySettings();
|
||||
applySetting("port");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_coord1_valueChanged(double value)
|
||||
@ -764,8 +752,7 @@ void GS232ControllerGUI::on_azimuthOffset_valueChanged(double value)
|
||||
m_inputAzOffset = value;
|
||||
}
|
||||
m_settings.m_azimuthOffset = (float) value;
|
||||
m_settingsKeys.append("azimuthOffset");
|
||||
applySettings();
|
||||
applySetting("azimuthOffset");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_elevationOffset_valueChanged(double value)
|
||||
@ -774,58 +761,50 @@ void GS232ControllerGUI::on_elevationOffset_valueChanged(double value)
|
||||
m_inputElOffset = value;
|
||||
}
|
||||
m_settings.m_elevationOffset = (float) value;
|
||||
m_settingsKeys.append("elevationOffset");
|
||||
applySettings();
|
||||
applySetting("elevationOffset");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_azimuthMin_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_azimuthMin = value;
|
||||
m_settingsKeys.append("azimuthMin");
|
||||
applySettings();
|
||||
applySetting("azimuthMin");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_azimuthMax_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_azimuthMax = value;
|
||||
m_settingsKeys.append("azimuthMax");
|
||||
applySettings();
|
||||
applySetting("azimuthMax");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_elevationMin_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_elevationMin = value;
|
||||
m_settingsKeys.append("elevationMin");
|
||||
applySettings();
|
||||
applySetting("elevationMin");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_elevationMax_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_elevationMax = value;
|
||||
m_settingsKeys.append("elevationMax");
|
||||
applySettings();
|
||||
applySetting("elevationMax");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_tolerance_valueChanged(double value)
|
||||
{
|
||||
m_settings.m_tolerance = value;
|
||||
m_settingsKeys.append("tolerance");
|
||||
applySettings();
|
||||
applySetting("tolerance");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_precision_valueChanged(int value)
|
||||
{
|
||||
m_settings.m_precision = value;
|
||||
setPrecision();
|
||||
m_settingsKeys.append("precision");
|
||||
applySettings();
|
||||
applySetting("precision");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_coordinates_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_coordinates = (GS232ControllerSettings::Coordinates)index;
|
||||
m_settingsKeys.append("coordinates");
|
||||
applySettings();
|
||||
applySetting("coordinates");
|
||||
|
||||
float coord1, coord2;
|
||||
azElToDisplay(m_settings.m_azimuth, m_settings.m_elevation, coord1, coord2);
|
||||
@ -880,8 +859,7 @@ void GS232ControllerGUI::on_track_stateChanged(int state)
|
||||
ui->targetName->setText("");
|
||||
}
|
||||
|
||||
m_settingsKeys.append("track");
|
||||
applySettings();
|
||||
applySetting("track");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_sources_currentTextChanged(const QString& text)
|
||||
@ -889,36 +867,31 @@ void GS232ControllerGUI::on_sources_currentTextChanged(const QString& text)
|
||||
qDebug("GS232ControllerGUI::on_sources_currentTextChanged: %s", qPrintable(text));
|
||||
m_settings.m_source = text;
|
||||
ui->targetName->setText("");
|
||||
m_settingsKeys.append("source");
|
||||
applySettings();
|
||||
applySetting("source");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_dfmTrack_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_dfmTrackOn = checked;
|
||||
m_settingsKeys.append("dfmTrackOn");
|
||||
applySettings();
|
||||
applySetting("dfmTrackOn");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_dfmLubePumps_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_dfmLubePumpsOn = checked;
|
||||
m_settingsKeys.append("dfmLubePumpsOn");
|
||||
applySettings();
|
||||
applySetting("dfmLubePumpsOn");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_dfmBrakes_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_dfmBrakesOn = checked;
|
||||
m_settingsKeys.append("dfmBrakesOn");
|
||||
applySettings();
|
||||
applySetting("dfmBrakesOn");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_dfmDrives_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_dfmDrivesOn = checked;
|
||||
m_settingsKeys.append("dfmDrivesOn");
|
||||
applySettings();
|
||||
applySetting("dfmDrivesOn");
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::on_dfmShowStatus_clicked()
|
||||
@ -983,17 +956,28 @@ void GS232ControllerGUI::updateStatus()
|
||||
}
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::applySettings(bool force)
|
||||
void GS232ControllerGUI::applySetting(const QString& settingsKey)
|
||||
{
|
||||
applySettings({settingsKey});
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::applySettings(const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
m_settingsKeys.append(settingsKeys);
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
GS232Controller::MsgConfigureGS232Controller* message = GS232Controller::MsgConfigureGS232Controller::create(m_settings, m_settingsKeys, force);
|
||||
m_gs232Controller->getInputMessageQueue()->push(message);
|
||||
m_settingsKeys.clear();
|
||||
}
|
||||
|
||||
m_settingsKeys.clear();
|
||||
}
|
||||
|
||||
void GS232ControllerGUI::applyAllSettings()
|
||||
{
|
||||
applySettings(QStringList(), true);
|
||||
}
|
||||
|
||||
|
||||
void GS232ControllerGUI::makeUIConnections()
|
||||
{
|
||||
QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &GS232ControllerGUI::on_startStop_toggled);
|
||||
|
@ -85,12 +85,14 @@ private:
|
||||
virtual ~GS232ControllerGUI();
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings(bool force = false);
|
||||
void applySetting(const QString& settingsKey);
|
||||
void applySettings(const QStringList& settingsKeys, bool force = false);
|
||||
void applyAllSettings();
|
||||
void displaySettings();
|
||||
void setProtocol(GS232ControllerSettings::Protocol protocol);
|
||||
void setPrecision();
|
||||
void updateConnectionWidgets();
|
||||
void updatePipeList(const QList<MainCore::AvailableChannelOrFeature>& sources);
|
||||
void updatePipeList(const AvailableChannelOrFeatureList& sources, const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void updateSerialPortList();
|
||||
void updateSerialPortList(const QStringList& serialPorts);
|
||||
bool handleMessage(const Message& message);
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// Copyright (C) 2015-2017, 2019-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020-2021, 2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2021, 2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -26,14 +26,6 @@
|
||||
#include "gs232controllersettings.h"
|
||||
#include "inputcontrollersettings.h"
|
||||
|
||||
const QStringList GS232ControllerSettings::m_pipeTypes = {
|
||||
QStringLiteral("ADSBDemod"),
|
||||
QStringLiteral("Map"),
|
||||
QStringLiteral("SkyMap"),
|
||||
QStringLiteral("StarTracker"),
|
||||
QStringLiteral("SatelliteTracker")
|
||||
};
|
||||
|
||||
const QStringList GS232ControllerSettings::m_pipeURIs = {
|
||||
QStringLiteral("sdrangel.channel.adsbdemod"),
|
||||
QStringLiteral("sdrangel.feature.map"),
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// Copyright (C) 2015-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020-2021, 2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2021, 2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -81,7 +81,6 @@ struct GS232ControllerSettings
|
||||
void applySettings(const QStringList& settingsKeys, const GS232ControllerSettings& settings);
|
||||
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
|
||||
|
||||
static const QStringList m_pipeTypes;
|
||||
static const QStringList m_pipeURIs;
|
||||
};
|
||||
|
||||
|
@ -185,8 +185,8 @@ The controller uses the 'P' and 'p' commands to set and get azimuth and elevatio
|
||||
|
||||
Full details of the API can be found in the Swagger documentation. Here is a quick example of how to set the azimuth and elevation from the command line:
|
||||
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "GS232Controller", "GS232ControllerSettings": { "azimuth": 180, "elevation": 45 }}'
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "GS232Controller", "GS232ControllerSettings": { "azimuth": 180, "elevation": 45 }}'
|
||||
|
||||
To start sending commands to the rotator:
|
||||
|
||||
curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/run"
|
||||
curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/feature/0/run"
|
||||
|
@ -97,8 +97,8 @@ The statistics fields display the statistics for the current test:
|
||||
|
||||
Full details of the API can be found in the Swagger documentation. Here is a quick example of how to set the azimuth and elevation from the command line:
|
||||
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "PERTester", "PERTesterSettings": { "packetCount": 100 }}'
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "PERTester", "PERTesterSettings": { "packetCount": 100 }}'
|
||||
|
||||
To start sending the test:
|
||||
|
||||
curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/run"
|
||||
curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/feature/0/run"
|
||||
|
@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2021-2022 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -41,7 +41,8 @@ const char* const Radiosonde::m_featureIdURI = "sdrangel.feature.radiosonde";
|
||||
const char* const Radiosonde::m_featureId = "Radiosonde";
|
||||
|
||||
Radiosonde::Radiosonde(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface)
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_availableChannelHandler({"sdrangel.channel.radiosondedemod"}, QStringList{"radiosonde"})
|
||||
{
|
||||
qDebug("Radiosonde::Radiosonde: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||
setObjectName(m_featureId);
|
||||
@ -54,22 +55,22 @@ Radiosonde::Radiosonde(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
this,
|
||||
&Radiosonde::networkManagerFinished
|
||||
);
|
||||
scanAvailableChannels();
|
||||
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&Radiosonde::handleChannelAdded
|
||||
);
|
||||
&Radiosonde::handleChannelMessageQueue);
|
||||
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
Radiosonde::~Radiosonde()
|
||||
{
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
&m_availableChannelHandler,
|
||||
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||
this,
|
||||
&Radiosonde::handleChannelAdded
|
||||
&Radiosonde::handleChannelMessageQueue
|
||||
);
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
@ -362,90 +363,6 @@ void Radiosonde::networkManagerFinished(QNetworkReply *reply)
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void Radiosonde::scanAvailableChannels()
|
||||
{
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
MessagePipes& messagePipes = mainCore->getMessagePipes();
|
||||
std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets();
|
||||
m_availableChannels.clear();
|
||||
|
||||
for (const auto& deviceSet : deviceSets)
|
||||
{
|
||||
DSPDeviceSourceEngine *deviceSourceEngine = deviceSet->m_deviceSourceEngine;
|
||||
|
||||
if (deviceSourceEngine)
|
||||
{
|
||||
for (int chi = 0; chi < deviceSet->getNumberOfChannels(); chi++)
|
||||
{
|
||||
ChannelAPI *channel = deviceSet->getChannelAt(chi);
|
||||
|
||||
if ((channel->getURI() == "sdrangel.channel.radiosondedemod") && !m_availableChannels.contains(channel))
|
||||
{
|
||||
qDebug("Radiosonde::scanAvailableChannels: register %d:%d (%p)", deviceSet->getIndex(), chi, channel);
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(channel, this, "radiosonde");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleChannelMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
QObject::connect(
|
||||
pipe,
|
||||
&ObjectPipe::toBeDeleted,
|
||||
this,
|
||||
&Radiosonde::handleMessagePipeToBeDeleted
|
||||
);
|
||||
m_availableChannels.insert(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Radiosonde::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
qDebug("Radiosonde::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)",
|
||||
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
||||
std::vector<DeviceSet*>& deviceSets = MainCore::instance()->getDeviceSets();
|
||||
DeviceSet *deviceSet = deviceSets[deviceSetIndex];
|
||||
DSPDeviceSourceEngine *deviceSourceEngine = deviceSet->m_deviceSourceEngine;
|
||||
|
||||
if (deviceSourceEngine && (channel->getURI() == "sdrangel.channel.radiosondedemod"))
|
||||
{
|
||||
if (!m_availableChannels.contains(channel))
|
||||
{
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(channel, this, "radiosonde");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleChannelMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
QObject::connect(
|
||||
pipe,
|
||||
&ObjectPipe::toBeDeleted,
|
||||
this,
|
||||
&Radiosonde::handleMessagePipeToBeDeleted
|
||||
);
|
||||
m_availableChannels.insert(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Radiosonde::handleMessagePipeToBeDeleted(int reason, QObject* object)
|
||||
{
|
||||
if ((reason == 0) && m_availableChannels.contains((ChannelAPI*) object)) // producer (channel)
|
||||
{
|
||||
qDebug("Radiosonde::handleMessagePipeToBeDeleted: removing channel at (%p)", object);
|
||||
m_availableChannels.remove((ChannelAPI*) object);
|
||||
}
|
||||
}
|
||||
|
||||
void Radiosonde::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||
{
|
||||
Message* message;
|
||||
|
@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||
// Copyright (C) 2021-2022 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include "feature/feature.h"
|
||||
#include "util/message.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
|
||||
#include "radiosondesettings.h"
|
||||
|
||||
@ -101,7 +102,8 @@ public:
|
||||
|
||||
private:
|
||||
RadiosondeSettings m_settings;
|
||||
QSet<ChannelAPI*> m_availableChannels;
|
||||
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||
AvailableChannelOrFeatureList m_availableChannels;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
@ -110,12 +112,9 @@ private:
|
||||
void stop();
|
||||
void applySettings(const RadiosondeSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const RadiosondeSettings& settings, bool force);
|
||||
void scanAvailableChannels();
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
||||
};
|
||||
|
||||
|
@ -216,12 +216,12 @@ Icons are by Freepik from Flaticon https://www.flaticon.com/
|
||||
|
||||
Full details of the API can be found in the Swagger documentation. Here is a quick example of how to set the satellites to track:
|
||||
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "satellites": [ "NOAA 15", "NOAA 19" ] }}'
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "satellites": [ "NOAA 15", "NOAA 19" ] }}'
|
||||
|
||||
And how to set the target:
|
||||
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "target": "NOAA 15" }}'
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "target": "NOAA 15" }}'
|
||||
|
||||
Or, to set the device settings:
|
||||
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "deviceSettings": [ { "satellite": "ISS", "deviceSettings": [ { "deviceSet": "R0", "doppler": [0], "frequency": 0, "presetDescription": Sat", "presetFrequency": 145.825, "presetGroup": "ISS Digi", "startOnAOS": 1, "startStopFileSinks": 1, "stopOnLOS": 1}] } ] }}'
|
||||
curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "deviceSettings": [ { "satellite": "ISS", "deviceSettings": [ { "deviceSet": "R0", "doppler": [0], "frequency": 0, "presetDescription": Sat", "presetFrequency": 145.825, "presetGroup": "ISS Digi", "startOnAOS": 1, "startStopFileSinks": 1, "stopOnLOS": 1}] } ] }}'
|
||||
|
@ -9,8 +9,8 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
var esaskyFrame;
|
||||
var antennaHpbw = 5.0;
|
||||
var showAntenna = false;
|
||||
var antennaHpbw = 5.0;
|
||||
var showAntenna = false;
|
||||
|
||||
// API reference: https://www.cosmos.esa.int/web/esdc/esasky-javascript-api
|
||||
function on_ready() {
|
||||
@ -145,26 +145,26 @@
|
||||
|
||||
function showAntennaFoV(ra, dec) {
|
||||
var cmd =
|
||||
{
|
||||
{
|
||||
event: 'overlayFootprints',
|
||||
content: {
|
||||
'overlaySet':
|
||||
{
|
||||
'type': 'FootprintListOverlay',
|
||||
'overlayName': 'Antenna FoV',
|
||||
'cooframe': 'J2000',
|
||||
'color': 'white',
|
||||
'lineWidth': 5,
|
||||
'skyObjectList': [
|
||||
{
|
||||
'name': 'Antenna FoV',
|
||||
'id': 1,
|
||||
'stcs': 'CIRCLE J2000 ' + ra + ' ' + dec + ' ' + (antennaHpbw / 2.0),
|
||||
'ra_deg': ra,
|
||||
'dec_deg': dec
|
||||
}]
|
||||
}
|
||||
}
|
||||
content: {
|
||||
'overlaySet':
|
||||
{
|
||||
'type': 'FootprintListOverlay',
|
||||
'overlayName': 'Antenna FoV',
|
||||
'cooframe': 'J2000',
|
||||
'color': 'white',
|
||||
'lineWidth': 5,
|
||||
'skyObjectList': [
|
||||
{
|
||||
'name': 'Antenna FoV',
|
||||
'id': 1,
|
||||
'stcs': 'CIRCLE J2000 ' + ra + ' ' + dec + ' ' + (antennaHpbw / 2.0),
|
||||
'ra_deg': ra,
|
||||
'dec_deg': dec
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
esaskyFrame.contentWindow.postMessage(cmd, 'https://sky.esa.int');
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ void SkyMapGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||
(void) rollDown;
|
||||
|
||||
getRollupContents()->saveState(m_rollupState);
|
||||
applySetting("rollupState");
|
||||
}
|
||||
|
||||
SkyMapGUI::SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
|
||||
@ -198,7 +199,8 @@ SkyMapGUI::SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_featureUISet(featureUISet),
|
||||
m_doApplySettings(true),
|
||||
m_source(nullptr)
|
||||
m_source(nullptr),
|
||||
m_availableChannelOrFeatureHandler(SkyMapSettings::m_pipeURIs, {"target", "skymap.target"})
|
||||
{
|
||||
m_feature = feature;
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
@ -255,11 +257,8 @@ SkyMapGUI::SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *
|
||||
makeUIConnections();
|
||||
m_resizer.enableChildMouseTracking();
|
||||
|
||||
QObject::connect(MainCore::instance(), &MainCore::featureAdded, this, &SkyMapGUI::handleFeatureAdded);
|
||||
QObject::connect(MainCore::instance(), &MainCore::channelAdded, this, &SkyMapGUI::handleChannelAdded);
|
||||
QObject::connect(MainCore::instance(), &MainCore::featureRemoved, this, &SkyMapGUI::handleFeatureRemoved);
|
||||
QObject::connect(MainCore::instance(), &MainCore::channelRemoved, this, &SkyMapGUI::handleChannelRemoved);
|
||||
updateSourceList();
|
||||
QObject::connect(&m_availableChannelOrFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &SkyMapGUI::updateSourceList);
|
||||
m_availableChannelOrFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||
|
||||
connect(&m_wtml, &WTML::dataUpdated, this, &SkyMapGUI::wtmlUpdated);
|
||||
m_wtml.getData();
|
||||
@ -267,11 +266,7 @@ SkyMapGUI::SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *
|
||||
|
||||
SkyMapGUI::~SkyMapGUI()
|
||||
{
|
||||
QObject::disconnect(MainCore::instance(), &MainCore::featureAdded, this, &SkyMapGUI::handleFeatureAdded);
|
||||
QObject::disconnect(MainCore::instance(), &MainCore::channelAdded, this, &SkyMapGUI::handleChannelAdded);
|
||||
QObject::disconnect(MainCore::instance(), &MainCore::featureRemoved, this, &SkyMapGUI::handleFeatureRemoved);
|
||||
QObject::disconnect(MainCore::instance(), &MainCore::channelRemoved, this, &SkyMapGUI::handleChannelRemoved);
|
||||
|
||||
QObject::disconnect(&m_availableChannelOrFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &SkyMapGUI::updateSourceList);
|
||||
if (m_webServer)
|
||||
{
|
||||
m_webServer->close();
|
||||
@ -350,7 +345,6 @@ void SkyMapGUI::on_source_currentIndexChanged(int index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SkyMapGUI::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
|
||||
{
|
||||
qDebug() << "SkyMapGUI::renderProcessTerminated: " << terminationStatus << "exitCode" << exitCode;
|
||||
@ -472,22 +466,17 @@ void SkyMapGUI::applySetting(const QString& settingsKey)
|
||||
|
||||
void SkyMapGUI::applySettings(const QStringList& settingsKeys, bool force)
|
||||
{
|
||||
m_settingsKeys.append(settingsKeys);
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
SkyMap::MsgConfigureSkyMap* message = SkyMap::MsgConfigureSkyMap::create(m_settings, settingsKeys, force);
|
||||
SkyMap::MsgConfigureSkyMap* message = SkyMap::MsgConfigureSkyMap::create(m_settings, m_settingsKeys, force);
|
||||
m_skymap->getInputMessageQueue()->push(message);
|
||||
m_settingsKeys.clear();
|
||||
|
||||
m_availableChannelOrFeatureHandler.deregisterPipes(m_source, this, {"target", "skymap.target"});
|
||||
|
||||
QObject *oldSource = m_source;
|
||||
QObject *source = MainCore::getAvailableChannelOrFeatureByLongId(m_settings.m_source, m_availableChannelOrFeatures);
|
||||
if (source)
|
||||
{
|
||||
registerPipe(source);
|
||||
m_source = source;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_source = nullptr;
|
||||
}
|
||||
m_source = m_availableChannelOrFeatureHandler.registerPipes(m_settings.m_source, this, {"target", "skymap.target"});
|
||||
|
||||
// When we change plugins, default to current date and time and My Position, until we get something different
|
||||
if (oldSource && !m_source)
|
||||
@ -497,6 +486,7 @@ void SkyMapGUI::applySettings(const QStringList& settingsKeys, bool force)
|
||||
MainCore::instance()->getSettings().getLongitude(),
|
||||
MainCore::instance()->getSettings().getAltitude());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,91 +774,85 @@ void SkyMapGUI::receivedEvent(const QJsonObject &obj)
|
||||
}
|
||||
}
|
||||
|
||||
// Loaded via WTML
|
||||
QStringList wwtBackgrounds;
|
||||
|
||||
const QStringList wwtPlanets = {
|
||||
"Sun",
|
||||
"Mercury",
|
||||
"Venus",
|
||||
"Earth",
|
||||
"Moon",
|
||||
"Mars",
|
||||
"Jupiter",
|
||||
"Saturn",
|
||||
"Uranus",
|
||||
"Neptune",
|
||||
"Pluto",
|
||||
"Io",
|
||||
"Europa",
|
||||
"Ganymede",
|
||||
"Callisto"
|
||||
static const QStringList wwtPlanets = {
|
||||
QStringLiteral("Sun"),
|
||||
QStringLiteral("Mercury"),
|
||||
QStringLiteral("Venus"),
|
||||
QStringLiteral("Earth"),
|
||||
QStringLiteral("Moon"),
|
||||
QStringLiteral("Mars"),
|
||||
QStringLiteral("Jupiter"),
|
||||
QStringLiteral("Saturn"),
|
||||
QStringLiteral("Uranus"),
|
||||
QStringLiteral("Neptune"),
|
||||
QStringLiteral("Pluto"),
|
||||
QStringLiteral("Io"),
|
||||
QStringLiteral("Europa"),
|
||||
QStringLiteral("Ganymede"),
|
||||
QStringLiteral("Callisto")
|
||||
};
|
||||
|
||||
const QStringList wwtPlanetIDs = {
|
||||
"Sun",
|
||||
"Mercury",
|
||||
"Venus",
|
||||
"Bing Maps Aerial", //"Earth",
|
||||
"Moon",
|
||||
"Visible Imagery", // Mars
|
||||
"Jupiter",
|
||||
"Saturn",
|
||||
"Uranus",
|
||||
"Neptune",
|
||||
"Pluto (New Horizons)",
|
||||
"Io",
|
||||
"Europa",
|
||||
"Ganymede",
|
||||
"Callisto"
|
||||
static const QStringList wwtPlanetIDs = {
|
||||
QStringLiteral("Sun"),
|
||||
QStringLiteral("Mercury"),
|
||||
QStringLiteral("Venus"),
|
||||
QStringLiteral("Bing Maps Aerial"), //"Earth",
|
||||
QStringLiteral("Moon"),
|
||||
QStringLiteral("Visible Imagery"), // Mars
|
||||
QStringLiteral("Jupiter"),
|
||||
QStringLiteral("Saturn"),
|
||||
QStringLiteral("Uranus"),
|
||||
QStringLiteral("Neptune"),
|
||||
QStringLiteral("Pluto (New Horizons)"),
|
||||
QStringLiteral("Io"),
|
||||
QStringLiteral("Europa"),
|
||||
QStringLiteral("Ganymede"),
|
||||
QStringLiteral("Callisto")
|
||||
};
|
||||
|
||||
// From https://github.com/cds-astro/aladin-lite/blob/master/src/js/ImageLayer.js
|
||||
const QStringList aladinBackgrounds = {
|
||||
"DSS colored",
|
||||
"DSS2 Red (F+R)",
|
||||
"2MASS colored",
|
||||
"Density map for Gaia EDR3 (I/350/gaiaedr3)",
|
||||
"PanSTARRS DR1 g",
|
||||
"PanSTARRS DR1 color",
|
||||
"DECaPS DR1 color",
|
||||
"Fermi color",
|
||||
"Halpha",
|
||||
"GALEXGR6_7 NUV",
|
||||
"IRIS colored",
|
||||
"Mellinger colored",
|
||||
"SDSS9 colored",
|
||||
"SDSS9 band-g",
|
||||
"IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)",
|
||||
"VTSS-Ha",
|
||||
"XMM PN colored",
|
||||
"AllWISE color",
|
||||
"GLIMPSE360"
|
||||
static const QStringList aladinBackgrounds = {
|
||||
QStringLiteral("DSS colored"),
|
||||
QStringLiteral("DSS2 Red (F+R)"),
|
||||
QStringLiteral("2MASS colored"),
|
||||
QStringLiteral("Density map for Gaia EDR3 (I/350/gaiaedr3)"),
|
||||
QStringLiteral("PanSTARRS DR1 g"),
|
||||
QStringLiteral("PanSTARRS DR1 color"),
|
||||
QStringLiteral("DECaPS DR1 color"),
|
||||
QStringLiteral("Fermi color"),
|
||||
QStringLiteral("Halpha"),
|
||||
QStringLiteral("GALEXGR6_7 NUV"),
|
||||
QStringLiteral("IRIS colored"),
|
||||
QStringLiteral("Mellinger colored"),
|
||||
QStringLiteral("SDSS9 colored"),
|
||||
QStringLiteral("SDSS9 band-g"),
|
||||
QStringLiteral("IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)"),
|
||||
QStringLiteral("VTSS-Ha"),
|
||||
QStringLiteral("XMM PN colored"),
|
||||
QStringLiteral("AllWISE color"),
|
||||
QStringLiteral("GLIMPSE360")
|
||||
};
|
||||
|
||||
const QStringList aladinBackgroundIDs = {
|
||||
"P/DSS2/color",
|
||||
"P/DSS2/red",
|
||||
"P/2MASS/color",
|
||||
"P/DM/I/350/gaiaedr3",
|
||||
"P/PanSTARRS/DR1/g",
|
||||
"P/PanSTARRS/DR1/color-z-zg-g",
|
||||
"P/DECaPS/DR1/color",
|
||||
"P/Fermi/color",
|
||||
"P/Finkbeiner",
|
||||
"P/GALEXGR6_7/NUV",
|
||||
"P/IRIS/color",
|
||||
"P/Mellinger/color",
|
||||
"P/SDSS9/color",
|
||||
"P/SDSS9/g",
|
||||
"P/SPITZER/color",
|
||||
"P/VTSS/Ha",
|
||||
"xcatdb/P/XMM/PN/color",
|
||||
"P/allWISE/color",
|
||||
"P/GLIMPSE360"
|
||||
};
|
||||
|
||||
const QStringList esaSkyBackgrounds = {
|
||||
static const QStringList aladinBackgroundIDs = {
|
||||
QStringLiteral("P/DSS2/color"),
|
||||
QStringLiteral("P/DSS2/red"),
|
||||
QStringLiteral("P/2MASS/color"),
|
||||
QStringLiteral("P/DM/I/350/gaiaedr3"),
|
||||
QStringLiteral("P/PanSTARRS/DR1/g"),
|
||||
QStringLiteral("P/PanSTARRS/DR1/color-z-zg-g"),
|
||||
QStringLiteral("P/DECaPS/DR1/color"),
|
||||
QStringLiteral("P/Fermi/color"),
|
||||
QStringLiteral("P/Finkbeiner"),
|
||||
QStringLiteral("P/GALEXGR6_7/NUV"),
|
||||
QStringLiteral("P/IRIS/color"),
|
||||
QStringLiteral("P/Mellinger/color"),
|
||||
QStringLiteral("P/SDSS9/color"),
|
||||
QStringLiteral("P/SDSS9/g"),
|
||||
QStringLiteral("P/SPITZER/color"),
|
||||
QStringLiteral("P/VTSS/Ha"),
|
||||
QStringLiteral("xcatdb/P/XMM/PN/color"),
|
||||
QStringLiteral("P/allWISE/color"),
|
||||
QStringLiteral("P/GLIMPSE360")
|
||||
};
|
||||
|
||||
QString SkyMapGUI::backgroundID(const QString& name)
|
||||
@ -906,7 +890,7 @@ void SkyMapGUI::updateBackgrounds()
|
||||
|
||||
if (m_settings.m_map == "WWT") {
|
||||
if (m_settings.m_projection == "Sky") {
|
||||
backgrounds = wwtBackgrounds;
|
||||
backgrounds = m_wwtBackgrounds;
|
||||
} else if (m_settings.m_projection == "Solar system") {
|
||||
backgrounds = wwtPlanets;
|
||||
} else {
|
||||
@ -936,11 +920,11 @@ void SkyMapGUI::updateBackgrounds()
|
||||
|
||||
void SkyMapGUI::wtmlUpdated(const QList<WTML::ImageSet>& dataSets)
|
||||
{
|
||||
wwtBackgrounds.clear();
|
||||
m_wwtBackgrounds.clear();
|
||||
for (int i = 0; i < dataSets.size(); i++)
|
||||
{
|
||||
if (dataSets[i].m_dataSetType == "Sky") {
|
||||
wwtBackgrounds.append(dataSets[i].m_name);
|
||||
m_wwtBackgrounds.append(dataSets[i].m_name);
|
||||
}
|
||||
}
|
||||
updateBackgrounds();
|
||||
@ -1027,10 +1011,18 @@ void SkyMapGUI::sendToRotator(const QString& name, double az, double alt)
|
||||
}
|
||||
}
|
||||
|
||||
void SkyMapGUI::updateSourceList()
|
||||
void SkyMapGUI::updateSourceList(const QStringList& renameFrom, const QStringList& renameTo)
|
||||
{
|
||||
m_availableChannelOrFeatures = MainCore::instance()->getAvailableChannelsAndFeatures(SkyMapSettings::m_pipeURIs);
|
||||
m_availableChannelOrFeatures = m_availableChannelOrFeatureHandler.getAvailableChannelOrFeatureList();
|
||||
|
||||
// Update source settting if it has been renamed
|
||||
if (renameFrom.contains(m_settings.m_source))
|
||||
{
|
||||
m_settings.m_source = renameTo[renameFrom.indexOf(m_settings.m_source)];
|
||||
applySetting("source"); // Only call after m_availableChannelOrFeatures has been updated
|
||||
}
|
||||
|
||||
int prevIdx = ui->source->currentIndex();
|
||||
ui->source->blockSignals(true);
|
||||
ui->source->clear();
|
||||
|
||||
@ -1038,89 +1030,37 @@ void SkyMapGUI::updateSourceList()
|
||||
ui->source->addItem(item.getLongId());
|
||||
}
|
||||
|
||||
// Select current setting, if exists
|
||||
// If not, make sure nothing selected, as channel may be created later on
|
||||
// Select current setting, if it exists
|
||||
// If not, and no prior setting, make sure nothing selected, as channel/feature may be created later on
|
||||
// If not found and something was previously selected, clear the setting, as probably deleted
|
||||
int idx = ui->source->findText(m_settings.m_source);
|
||||
if (idx >= 0)
|
||||
{
|
||||
ui->source->setCurrentIndex(idx);
|
||||
ui->track->setEnabled(true);
|
||||
}
|
||||
else
|
||||
else if (prevIdx == -1)
|
||||
{
|
||||
ui->source->setCurrentIndex(-1);
|
||||
ui->track->setChecked(false);
|
||||
ui->track->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.m_source = "";
|
||||
applySetting("source");
|
||||
}
|
||||
|
||||
ui->source->blockSignals(false);
|
||||
|
||||
// If no current settting, select first available
|
||||
if (m_settings.m_source.isEmpty())
|
||||
if (m_settings.m_source.isEmpty() && (ui->source->count() > 0))
|
||||
{
|
||||
ui->source->setCurrentIndex(0);
|
||||
on_source_currentIndexChanged(0);
|
||||
}
|
||||
}
|
||||
|
||||
void SkyMapGUI::handleFeatureAdded(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) feature;
|
||||
|
||||
updateSourceList();
|
||||
}
|
||||
|
||||
void SkyMapGUI::handleFeatureRemoved(int featureSetIndex, Feature *oldFeature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) oldFeature;
|
||||
|
||||
updateSourceList();
|
||||
}
|
||||
|
||||
void SkyMapGUI::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
(void) deviceSetIndex;
|
||||
(void) channel;
|
||||
|
||||
updateSourceList();
|
||||
}
|
||||
|
||||
void SkyMapGUI::handleChannelRemoved(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
(void) deviceSetIndex;
|
||||
(void) channel;
|
||||
|
||||
updateSourceList();
|
||||
}
|
||||
|
||||
void SkyMapGUI::registerPipe(QObject *object)
|
||||
{
|
||||
qDebug("SkyMapGUI::registerPipe: register %s (%p)", qPrintable(object->objectName()), object);
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(object, this, "target");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handlePipeMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
|
||||
pipe = messagePipes.registerProducerToConsumer(object, this, "skymap.target");
|
||||
messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handlePipeMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
|
||||
void SkyMapGUI::handlePipeMessageQueue(MessageQueue* messageQueue)
|
||||
{
|
||||
Message* message;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "feature/featuregui.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "settings/rollupstate.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "skymapsettings.h"
|
||||
@ -72,10 +73,12 @@ private:
|
||||
PluginAPI* m_pluginAPI;
|
||||
FeatureUISet* m_featureUISet;
|
||||
SkyMapSettings m_settings;
|
||||
QList<QString> m_settingsKeys;
|
||||
RollupState m_rollupState;
|
||||
bool m_doApplySettings;
|
||||
QList<MainCore::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
||||
QObject *m_source;
|
||||
AvailableChannelOrFeatureList m_availableChannelOrFeatures;
|
||||
AvailableChannelOrFeatureHandler m_availableChannelOrFeatureHandler;
|
||||
|
||||
SkyMap* m_skymap;
|
||||
MessageQueue m_inputMessageQueue;
|
||||
@ -90,6 +93,8 @@ private:
|
||||
double m_dec;
|
||||
QDateTime m_dateTime; //!< Date time from source plugin
|
||||
|
||||
QStringList m_wwtBackgrounds;
|
||||
|
||||
explicit SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
|
||||
virtual ~SkyMapGUI();
|
||||
|
||||
@ -112,8 +117,6 @@ private:
|
||||
void updateProjection();
|
||||
void find(const QString& text);
|
||||
void sendToRotator(const QString& name, double az, double alt);
|
||||
void updateSourceList();
|
||||
void registerPipe(QObject *object);
|
||||
|
||||
private slots:
|
||||
void onMenuDialogCalled(const QPoint &p);
|
||||
@ -140,11 +143,7 @@ private slots:
|
||||
void preferenceChanged(int elementType);
|
||||
void receivedEvent(const QJsonObject &obj);
|
||||
void wtmlUpdated(const QList<WTML::ImageSet>& dataSets);
|
||||
|
||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
||||
void handleFeatureRemoved(int featureSetIndex, Feature *oldFeature);
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleChannelRemoved(int deviceSetIndex, ChannelAPI *channel);
|
||||
void updateSourceList(const QStringList& renameFrom, const QStringList& renameTo);
|
||||
void handlePipeMessageQueue(MessageQueue* messageQueue);
|
||||
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -42,7 +42,8 @@
|
||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgConfigureStarTracker, Message)
|
||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgStartStop, Message)
|
||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgSetSolarFlux, Message)
|
||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgReportAvailableSatelliteTrackers, Message)
|
||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgRequestAvailableFeatures, Message)
|
||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgReportAvailableFeatures, Message)
|
||||
|
||||
const char* const StarTracker::m_featureIdURI = "sdrangel.feature.startracker";
|
||||
const char* const StarTracker::m_featureId = "StarTracker";
|
||||
@ -50,7 +51,9 @@ const char* const StarTracker::m_featureId = "StarTracker";
|
||||
StarTracker::StarTracker(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||
m_thread(nullptr),
|
||||
m_worker(nullptr)
|
||||
m_worker(nullptr),
|
||||
m_availableChannelHandler({"sdrangel.channel.radioastronomy"}, QStringList{"startracker.display"}),
|
||||
m_availableFeatureHandler({"sdrangel.feature.satellitetracker", "sdrangel.feature.skymap"})
|
||||
{
|
||||
qDebug("StarTracker::StarTracker: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||
setObjectName(m_featureId);
|
||||
@ -70,36 +73,17 @@ StarTracker::StarTracker(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||
m_temps.append(new FITS(":/startracker/startracker/408mhz_ra_dec.fits"));
|
||||
m_temps.append(new FITS(":/startracker/startracker/1420mhz_ra_dec.fits"));
|
||||
m_spectralIndex = new FITS(":/startracker/startracker/408mhz_ra_dec_spectral_index.fits");
|
||||
scanAvailableChannels();
|
||||
scanAvailableFeatures();
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
this,
|
||||
&StarTracker::handleChannelAdded
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureAdded,
|
||||
this,
|
||||
&StarTracker::handleFeatureAdded
|
||||
);
|
||||
QObject::connect(
|
||||
MainCore::instance(),
|
||||
&MainCore::featureRemoved,
|
||||
this,
|
||||
&StarTracker::handleFeatureRemoved
|
||||
);
|
||||
|
||||
QObject::connect(&m_availableChannelHandler, &AvailableChannelOrFeatureHandler::messageEnqueued, this, &StarTracker::handleChannelMessageQueue);
|
||||
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||
QObject::connect(&m_availableFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &StarTracker::featuresChanged);
|
||||
m_availableFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
StarTracker::~StarTracker()
|
||||
{
|
||||
QObject::disconnect(
|
||||
MainCore::instance(),
|
||||
&MainCore::channelAdded,
|
||||
this,
|
||||
&StarTracker::handleChannelAdded
|
||||
);
|
||||
QObject::disconnect(&m_availableChannelHandler, &AvailableChannelOrFeatureHandler::messageEnqueued, this, &StarTracker::handleChannelMessageQueue);
|
||||
QObject::disconnect(&m_availableFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &StarTracker::featuresChanged);
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
@ -176,6 +160,11 @@ bool StarTracker::handleMessage(const Message& cmd)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MsgRequestAvailableFeatures::match(cmd))
|
||||
{
|
||||
notifyUpdateFeatures();
|
||||
return true;
|
||||
}
|
||||
else if (MsgSetSolarFlux::match(cmd))
|
||||
{
|
||||
MsgSetSolarFlux& msg = (MsgSetSolarFlux&) cmd;
|
||||
@ -839,137 +828,18 @@ bool StarTracker::calcSkyTemperature(double frequency, double beamwidth, double
|
||||
}
|
||||
}
|
||||
|
||||
void StarTracker::scanAvailableChannels()
|
||||
void StarTracker::featuresChanged()
|
||||
{
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
MessagePipes& messagePipes = mainCore->getMessagePipes();
|
||||
std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets();
|
||||
m_availableChannels.clear();
|
||||
|
||||
for (const auto& deviceSet : deviceSets)
|
||||
{
|
||||
DSPDeviceSourceEngine *deviceSourceEngine = deviceSet->m_deviceSourceEngine;
|
||||
|
||||
if (deviceSourceEngine)
|
||||
{
|
||||
for (int chi = 0; chi < deviceSet->getNumberOfChannels(); chi++)
|
||||
{
|
||||
ChannelAPI *channel = deviceSet->getChannelAt(chi);
|
||||
|
||||
if (StarTrackerSettings::m_pipeURIs.contains(channel->getURI()) && !m_availableChannels.contains(channel))
|
||||
{
|
||||
qDebug("StarTracker::scanAvailableChannels: register %d:%d %s (%p)",
|
||||
deviceSet->getIndex(), chi, qPrintable(channel->getURI()), channel);
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(channel, this, "startracker.display");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleChannelMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
QObject::connect(
|
||||
pipe,
|
||||
&ObjectPipe::toBeDeleted,
|
||||
this,
|
||||
&StarTracker::handleMessagePipeToBeDeleted
|
||||
);
|
||||
m_availableChannels.insert(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_availableFeatures = m_availableFeatureHandler.getAvailableChannelOrFeatureList();
|
||||
notifyUpdateFeatures();
|
||||
}
|
||||
|
||||
void StarTracker::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
qDebug("StarTracker::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)",
|
||||
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
||||
DeviceSet *deviceSet = MainCore::instance()->getDeviceSets()[deviceSetIndex];
|
||||
DSPDeviceSourceEngine *deviceSourceEngine = deviceSet->m_deviceSourceEngine;
|
||||
|
||||
if (deviceSourceEngine && StarTrackerSettings::m_pipeURIs.contains(channel->getURI()))
|
||||
{
|
||||
if (!m_availableChannels.contains(channel))
|
||||
{
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(channel, this, "startracker.display");
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ this->handleChannelMessageQueue(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
QObject::connect(
|
||||
pipe,
|
||||
&ObjectPipe::toBeDeleted,
|
||||
this,
|
||||
&StarTracker::handleMessagePipeToBeDeleted
|
||||
);
|
||||
m_availableChannels.insert(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StarTracker::handleMessagePipeToBeDeleted(int reason, QObject* object)
|
||||
{
|
||||
if ((reason == 0) && m_availableChannels.contains((ChannelAPI*) object)) // producer (channel)
|
||||
{
|
||||
qDebug("StarTracker::handleMessagePipeToBeDeleted: removing channel at (%p)", object);
|
||||
m_availableChannels.remove((ChannelAPI*) object);
|
||||
}
|
||||
}
|
||||
|
||||
void StarTracker::scanAvailableFeatures()
|
||||
{
|
||||
qDebug("StarTracker::scanAvailableFeatures");
|
||||
MainCore *mainCore = MainCore::instance();
|
||||
std::vector<FeatureSet*>& featureSets = mainCore->getFeatureeSets();
|
||||
m_satelliteTrackers.clear();
|
||||
|
||||
for (const auto& featureSet : featureSets)
|
||||
{
|
||||
for (int fei = 0; fei < featureSet->getNumberOfFeatures(); fei++)
|
||||
{
|
||||
Feature *feature = featureSet->getFeatureAt(fei);
|
||||
|
||||
if ((feature->getURI() == "sdrangel.feature.satellitetracker") || (feature->getURI() == "sdrangel.feature.skymap"))
|
||||
{
|
||||
StarTrackerSettings::AvailableFeature satelliteTracker =
|
||||
StarTrackerSettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()};
|
||||
m_satelliteTrackers[feature] = satelliteTracker;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notifyUpdateSatelliteTrackers();
|
||||
}
|
||||
|
||||
void StarTracker::handleFeatureAdded(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) feature;
|
||||
|
||||
scanAvailableFeatures();
|
||||
}
|
||||
|
||||
void StarTracker::handleFeatureRemoved(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) feature;
|
||||
|
||||
scanAvailableFeatures();
|
||||
}
|
||||
|
||||
void StarTracker::notifyUpdateSatelliteTrackers()
|
||||
void StarTracker::notifyUpdateFeatures()
|
||||
{
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
MsgReportAvailableSatelliteTrackers *msg = MsgReportAvailableSatelliteTrackers::create();
|
||||
msg->getFeatures() = m_satelliteTrackers.values();
|
||||
MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create();
|
||||
msg->getFeatures() = m_availableFeatures;
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -22,11 +22,11 @@
|
||||
|
||||
#include <QThread>
|
||||
#include <QNetworkRequest>
|
||||
#include <QSet>
|
||||
|
||||
#include "feature/feature.h"
|
||||
#include "util/message.h"
|
||||
#include "util/fits.h"
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
|
||||
#include "startrackersettings.h"
|
||||
|
||||
@ -107,20 +107,34 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportAvailableSatelliteTrackers : public Message {
|
||||
class MsgRequestAvailableFeatures : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
QList<StarTrackerSettings::AvailableFeature>& getFeatures() { return m_availableFeatures; }
|
||||
|
||||
static MsgReportAvailableSatelliteTrackers* create() {
|
||||
return new MsgReportAvailableSatelliteTrackers();
|
||||
static MsgRequestAvailableFeatures* create() {
|
||||
return new MsgRequestAvailableFeatures();
|
||||
}
|
||||
|
||||
private:
|
||||
QList<StarTrackerSettings::AvailableFeature> m_availableFeatures;
|
||||
MsgRequestAvailableFeatures() :
|
||||
Message()
|
||||
{}
|
||||
};
|
||||
|
||||
MsgReportAvailableSatelliteTrackers() :
|
||||
class MsgReportAvailableFeatures : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
AvailableChannelOrFeatureList& getFeatures() { return m_availableFeatures; }
|
||||
|
||||
static MsgReportAvailableFeatures* create() {
|
||||
return new MsgReportAvailableFeatures();
|
||||
}
|
||||
|
||||
private:
|
||||
AvailableChannelOrFeatureList m_availableFeatures;
|
||||
|
||||
MsgReportAvailableFeatures() :
|
||||
Message()
|
||||
{}
|
||||
};
|
||||
@ -183,11 +197,13 @@ private:
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
QSet<ChannelAPI*> m_availableChannels;
|
||||
QHash<Feature*, StarTrackerSettings::AvailableFeature> m_satelliteTrackers;
|
||||
Weather *m_weather;
|
||||
float m_solarFlux;
|
||||
|
||||
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||
AvailableChannelOrFeatureHandler m_availableFeatureHandler;
|
||||
AvailableChannelOrFeatureList m_availableFeatures;
|
||||
|
||||
QList<FITS*> m_temps;
|
||||
FITS *m_spectralIndex;
|
||||
|
||||
@ -197,17 +213,12 @@ private:
|
||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const StarTrackerSettings& settings, bool force);
|
||||
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
|
||||
double applyBeam(const FITS *fits, double beamwidth, double ra, double dec, int& imgX, int& imgY) const;
|
||||
void scanAvailableChannels();
|
||||
void scanAvailableFeatures();
|
||||
void notifyUpdateSatelliteTrackers();
|
||||
void notifyUpdateFeatures();
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void weatherUpdated(float temperature, float pressure, float humidity);
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
||||
void handleFeatureRemoved(int featureSetIndex, Feature *feature);
|
||||
void featuresChanged();
|
||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2021-2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -220,17 +220,17 @@ bool StarTrackerGUI::handleMessage(const Message& message)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (StarTracker::MsgReportAvailableSatelliteTrackers::match(message))
|
||||
else if (StarTracker::MsgReportAvailableFeatures::match(message))
|
||||
{
|
||||
StarTracker::MsgReportAvailableSatelliteTrackers& report = (StarTracker::MsgReportAvailableSatelliteTrackers&) message;
|
||||
updateSatelliteTrackerList(report.getFeatures());
|
||||
StarTracker::MsgReportAvailableFeatures& report = (StarTracker::MsgReportAvailableFeatures&) message;
|
||||
updateFeatureList(report.getFeatures());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void StarTrackerGUI::updateSatelliteTrackerList(const QList<StarTrackerSettings::AvailableFeature>& satelliteTrackers)
|
||||
void StarTrackerGUI::updateFeatureList(const AvailableChannelOrFeatureList& features)
|
||||
{
|
||||
// Update list of plugins we can get target from
|
||||
ui->target->blockSignals(true);
|
||||
@ -242,9 +242,9 @@ void StarTrackerGUI::updateSatelliteTrackerList(const QList<StarTrackerSettings:
|
||||
bool found = false;
|
||||
if (text.contains("SatelliteTracker") || text.contains("SkyMap"))
|
||||
{
|
||||
for (const auto& satelliteTracker : satelliteTrackers)
|
||||
for (const auto& feature : features)
|
||||
{
|
||||
if (satelliteTracker.getName() == text)
|
||||
if (feature.getLongId() == text)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
@ -263,9 +263,9 @@ void StarTrackerGUI::updateSatelliteTrackerList(const QList<StarTrackerSettings:
|
||||
}
|
||||
|
||||
// Add new targets
|
||||
for (const auto& satelliteTracker : satelliteTrackers)
|
||||
for (const auto& feature : features)
|
||||
{
|
||||
QString name = satelliteTracker.getName();
|
||||
QString name = feature.getLongId();
|
||||
if (ui->target->findText(name) == -1) {
|
||||
ui->target->addItem(name);
|
||||
}
|
||||
@ -454,6 +454,9 @@ StarTrackerGUI::StarTrackerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet,
|
||||
|
||||
createGalacticLineOfSightScene();
|
||||
plotChart();
|
||||
|
||||
StarTracker::MsgRequestAvailableFeatures *message = StarTracker::MsgRequestAvailableFeatures::create();
|
||||
m_starTracker->getInputMessageQueue()->push(message);
|
||||
}
|
||||
|
||||
StarTrackerGUI::~StarTrackerGUI()
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "util/fits.h"
|
||||
#include "gui/httpdownloadmanagergui.h"
|
||||
#include "settings/rollupstate.h"
|
||||
#include "availablechannelorfeature.h"
|
||||
|
||||
#include "startrackersettings.h"
|
||||
|
||||
@ -169,7 +170,7 @@ private:
|
||||
void updateSolarFlux(bool all);
|
||||
void makeUIConnections();
|
||||
void limitAzElRange(double& azimuth, double& elevation) const;
|
||||
void updateSatelliteTrackerList(const QList<StarTrackerSettings::AvailableFeature>& satelliteTrackers);
|
||||
void updateFeatureList(const AvailableChannelOrFeatureList& features);
|
||||
|
||||
private slots:
|
||||
void onMenuDialogCalled(const QPoint &p);
|
||||
|
@ -23,14 +23,6 @@
|
||||
|
||||
#include "startrackersettings.h"
|
||||
|
||||
const QStringList StarTrackerSettings::m_pipeTypes = {
|
||||
QStringLiteral("RadioAstronomy")
|
||||
};
|
||||
|
||||
const QStringList StarTrackerSettings::m_pipeURIs = {
|
||||
QStringLiteral("sdrangel.channel.radioastronomy")
|
||||
};
|
||||
|
||||
StarTrackerSettings::StarTrackerSettings() :
|
||||
m_rollupState(nullptr)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// Copyright (C) 2015-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// Copyright (C) 2020-2021, 2023 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// Copyright (C) 2020-2024 Jon Beniston, M7RCE <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
@ -30,23 +30,6 @@ class Serializable;
|
||||
|
||||
struct StarTrackerSettings
|
||||
{
|
||||
struct AvailableFeature
|
||||
{
|
||||
int m_featureSetIndex;
|
||||
int m_featureIndex;
|
||||
QString m_type;
|
||||
|
||||
AvailableFeature() = default;
|
||||
AvailableFeature(const AvailableFeature&) = default;
|
||||
AvailableFeature& operator=(const AvailableFeature&) = default;
|
||||
bool operator==(const AvailableFeature& a) const {
|
||||
return (m_featureSetIndex == a.m_featureSetIndex) && (m_featureIndex == a.m_featureIndex) && (m_type == a.m_type);
|
||||
}
|
||||
QString getName() const {
|
||||
return QString("F%1:%2 %3").arg(m_featureSetIndex).arg(m_featureIndex).arg(m_type);
|
||||
}
|
||||
};
|
||||
|
||||
QString m_ra;
|
||||
QString m_dec;
|
||||
double m_latitude;
|
||||
@ -102,9 +85,6 @@ struct StarTrackerSettings
|
||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||
void applySettings(const QStringList& settingsKeys, const StarTrackerSettings& settings);
|
||||
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
|
||||
|
||||
static const QStringList m_pipeTypes;
|
||||
static const QStringList m_pipeURIs;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_FEATURE_STARTRACKERSETTINGS_H_
|
||||
|
@ -286,6 +286,8 @@ set(sdrbase_SOURCES
|
||||
|
||||
websockets/wsspectrum.cpp
|
||||
|
||||
availablechannelorfeature.cpp
|
||||
availablechannelorfeaturehandler.cpp
|
||||
mainparser.cpp
|
||||
maincore.cpp
|
||||
remotetcpsinkstarter.cpp
|
||||
@ -525,6 +527,8 @@ set(sdrbase_HEADERS
|
||||
|
||||
websockets/wsspectrum.h
|
||||
|
||||
availablechannelorfeature.h
|
||||
availablechannelorfeaturehandler.h
|
||||
mainparser.h
|
||||
maincore.h
|
||||
remotetcpsinkstarter.h
|
||||
|
54
sdrbase/availablechannelorfeature.cpp
Normal file
54
sdrbase/availablechannelorfeature.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Jon Beniston <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "availablechannelorfeature.h"
|
||||
#include "feature/feature.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "maincore.h"
|
||||
|
||||
int AvailableChannelOrFeatureList::indexOfObject(const QObject *object, int from) const
|
||||
{
|
||||
for (int index = from; index < size(); index++)
|
||||
{
|
||||
if (at(index).m_object == object) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AvailableChannelOrFeatureList::indexOfId(const QString& id, int from) const
|
||||
{
|
||||
for (int index = from; index < size(); index++)
|
||||
{
|
||||
if (at(index).getId() == id) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AvailableChannelOrFeatureList::indexOfLongId(const QString& longId, int from) const
|
||||
{
|
||||
for (int index = from; index < size(); index++)
|
||||
{
|
||||
if (at(index).getLongId() == longId) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
77
sdrbase/availablechannelorfeature.h
Normal file
77
sdrbase/availablechannelorfeature.h
Normal file
@ -0,0 +1,77 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Jon Beniston <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_AVAILABLECHANNELORFEATURE_H_
|
||||
#define SDRBASE_AVAILABLECHANNELORFEATURE_H_
|
||||
|
||||
#include "pipes/messagepipes.h"
|
||||
#include "export.h"
|
||||
|
||||
struct AvailableChannelOrFeature
|
||||
{
|
||||
QChar m_kind; //!< 'R' or 'T' for channel, 'M' for MIMO channel, 'F' for feature as from MainCore::getDeviceSetTypeId
|
||||
int m_superIndex; //!< Device Set index or Feature Set index
|
||||
int m_index; //!< Channel or Feature index
|
||||
int m_streamIndex; //!< For MIMO channels only
|
||||
QString m_type; //!< Plugin type (E.g. NFMDemod)
|
||||
QObject *m_object; //!< Pointer to the object (ChannelAPI or Feature object)
|
||||
|
||||
AvailableChannelOrFeature() = default;
|
||||
AvailableChannelOrFeature(const AvailableChannelOrFeature&) = default;
|
||||
AvailableChannelOrFeature& operator=(const AvailableChannelOrFeature&) = default;
|
||||
|
||||
bool operator==(const AvailableChannelOrFeature& a) const {
|
||||
return (m_kind == a.m_kind) && (m_superIndex == a.m_superIndex) && (m_index == a.m_index) && (m_type == a.m_type) && ((m_kind == 'M') && (m_streamIndex == a.m_streamIndex));
|
||||
}
|
||||
|
||||
QString getId() const { // Eg: "R3:4"
|
||||
QString id = QString("%1%2:%3").arg(m_kind).arg(m_superIndex).arg(m_index);
|
||||
if (m_kind == "M") {
|
||||
id.append(QString(".%1").arg(m_streamIndex));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
QString getLongId() const { // Eg: "F0:1 StarTracker"
|
||||
return QString("%1 %2").arg(getId()).arg(m_type);
|
||||
}
|
||||
};
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
inline uint qHash(const AvailableChannelOrFeature &c, uint seed = 0) noexcept
|
||||
{
|
||||
return qHash(c.getLongId(), seed);
|
||||
}
|
||||
#else
|
||||
size_t qHash(const AvailableChannelOrFeatureList &c, size_t seed = 0) noexcept
|
||||
{
|
||||
return qHash(c.getLongId(), seed);
|
||||
}
|
||||
#endif
|
||||
|
||||
class SDRBASE_API AvailableChannelOrFeatureList : public QList<AvailableChannelOrFeature>
|
||||
{
|
||||
public:
|
||||
AvailableChannelOrFeatureList() {}
|
||||
inline explicit AvailableChannelOrFeatureList(const AvailableChannelOrFeature &i) { append(i); }
|
||||
|
||||
int indexOfObject(const QObject *object, int from=0) const; //!< // Find index of entry containing specified object. -1 if not found.
|
||||
int indexOfId(const QString& longId, int from=0) const; //!< // Find index of entry with specified Id. -1 if not found.
|
||||
int indexOfLongId(const QString& longId, int from=0) const; //!< // Find index of entry with specified long Id. -1 if not found.
|
||||
};
|
||||
|
||||
#endif // SDRBASE_AVAILABLECHANNELORFEATURE_H_
|
173
sdrbase/availablechannelorfeaturehandler.cpp
Normal file
173
sdrbase/availablechannelorfeaturehandler.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Jon Beniston <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "availablechannelorfeaturehandler.h"
|
||||
#include "feature/feature.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "maincore.h"
|
||||
|
||||
void AvailableChannelOrFeatureHandler::init()
|
||||
{
|
||||
QObject::connect(MainCore::instance(), &MainCore::channelAdded, this, &AvailableChannelOrFeatureHandler::handleChannelAdded);
|
||||
QObject::connect(MainCore::instance(), &MainCore::channelRemoved, this, &AvailableChannelOrFeatureHandler::handleChannelRemoved);
|
||||
QObject::connect(MainCore::instance(), &MainCore::featureAdded, this, &AvailableChannelOrFeatureHandler::handleFeatureAdded);
|
||||
QObject::connect(MainCore::instance(), &MainCore::featureRemoved, this, &AvailableChannelOrFeatureHandler::handleFeatureRemoved);
|
||||
// Don't call scanAvailableChannelsAndFeatures() here, as channelsOrFeaturesChanged slot will not yet be connected
|
||||
// Owner should call scanAvailableChannelsAndFeatures after connection
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::scanAvailableChannelsAndFeatures()
|
||||
{
|
||||
// Get current list of channels and features with specified URIs
|
||||
AvailableChannelOrFeatureList availableChannelOrFeatureList = MainCore::instance()->getAvailableChannelsAndFeatures(m_uris, m_kinds);
|
||||
|
||||
// Look for new channels or features
|
||||
for (const auto& channelOrFeature : availableChannelOrFeatureList)
|
||||
{
|
||||
if (!m_availableChannelOrFeatureList.contains(channelOrFeature))
|
||||
{
|
||||
// For MIMO channels, get notified when stream index changes
|
||||
if (channelOrFeature.m_kind == 'M')
|
||||
{
|
||||
ChannelAPI *channel = qobject_cast<ChannelAPI *>(channelOrFeature.m_object);
|
||||
if (channel) {
|
||||
QObject::connect(channel, &ChannelAPI::streamIndexChanged, this, &AvailableChannelOrFeatureHandler::handleStreamIndexChanged);
|
||||
}
|
||||
}
|
||||
// Register pipes for any new channels or features
|
||||
for (const auto& pipeName: m_pipeNames) {
|
||||
registerPipe(pipeName, channelOrFeature.m_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if list has changed
|
||||
bool changes = m_availableChannelOrFeatureList != availableChannelOrFeatureList;
|
||||
|
||||
// Check to see if anything has been renamed, due to indexes changing after device/channel/feature removal
|
||||
// or if stream index was changed
|
||||
QStringList renameFrom;
|
||||
QStringList renameTo;
|
||||
for (const auto& channelOrFeature : availableChannelOrFeatureList)
|
||||
{
|
||||
int index = m_availableChannelOrFeatureList.indexOfObject(channelOrFeature.m_object);
|
||||
if (index >= 0)
|
||||
{
|
||||
const AvailableChannelOrFeature& oldEntry = m_availableChannelOrFeatureList.at(index);
|
||||
if ((oldEntry.m_superIndex != channelOrFeature.m_superIndex)
|
||||
|| (oldEntry.m_index != channelOrFeature.m_index)
|
||||
|| ((channelOrFeature.m_kind == 'M') && (oldEntry.m_streamIndex != channelOrFeature.m_streamIndex))
|
||||
)
|
||||
{
|
||||
renameFrom.append(oldEntry.getId());
|
||||
renameTo.append(channelOrFeature.getId());
|
||||
renameFrom.append(oldEntry.getLongId());
|
||||
renameTo.append(channelOrFeature.getLongId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_availableChannelOrFeatureList = availableChannelOrFeatureList;
|
||||
|
||||
// Signal if list has changed
|
||||
if (changes) {
|
||||
emit channelsOrFeaturesChanged(renameFrom, renameTo);
|
||||
}
|
||||
}
|
||||
|
||||
QObject* AvailableChannelOrFeatureHandler::registerPipes(const QString& longIdFrom, QObject* to, const QStringList& pipeNames)
|
||||
{
|
||||
int index = m_availableChannelOrFeatureList.indexOfLongId(longIdFrom);
|
||||
if (index >= 0)
|
||||
{
|
||||
QObject *object = m_availableChannelOrFeatureList[index].m_object;
|
||||
for (const auto& pipeName : pipeNames) {
|
||||
registerPipe(pipeName, object);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::deregisterPipes(QObject* from, QObject* to, const QStringList& pipeNames)
|
||||
{
|
||||
// Don't dereference 'from' here, as it may have been deleted
|
||||
if (from)
|
||||
{
|
||||
qDebug("AvailableChannelOrFeatureHandler::deregisterPipes: unregister (%p)", from);
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
messagePipes.unregisterProducerToConsumer(from, to, "target");
|
||||
}
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::registerPipe(const QString& pipeName, QObject *channelOrFeature)
|
||||
{
|
||||
qDebug("MessagePipeHandler::registerPipe: register %s (%p)", qPrintable(channelOrFeature->objectName()), channelOrFeature);
|
||||
MessagePipes& messagePipes = MainCore::instance()->getMessagePipes();
|
||||
|
||||
ObjectPipe *pipe = messagePipes.registerProducerToConsumer(channelOrFeature, this, pipeName);
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
QObject::connect(
|
||||
messageQueue,
|
||||
&MessageQueue::messageEnqueued,
|
||||
this,
|
||||
[=](){ emit messageEnqueued(messageQueue); },
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
(void) deviceSetIndex;
|
||||
(void) channel;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::handleChannelRemoved(int deviceSetIndex, ChannelAPI *channel)
|
||||
{
|
||||
(void) deviceSetIndex;
|
||||
(void) channel;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::handleStreamIndexChanged(int streamIndex)
|
||||
{
|
||||
(void) streamIndex;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::handleFeatureAdded(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) feature;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
||||
|
||||
void AvailableChannelOrFeatureHandler::handleFeatureRemoved(int featureSetIndex, Feature *feature)
|
||||
{
|
||||
(void) featureSetIndex;
|
||||
(void) feature;
|
||||
|
||||
scanAvailableChannelsAndFeatures();
|
||||
}
|
86
sdrbase/availablechannelorfeaturehandler.h
Normal file
86
sdrbase/availablechannelorfeaturehandler.h
Normal file
@ -0,0 +1,86 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2024 Jon Beniston <jon@beniston.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SDRBASE_AVAILABLECHANNELORFEATUREHANDLER_H_
|
||||
#define SDRBASE_AVAILABLECHANNELORFEATUREHANDLER_H_
|
||||
|
||||
#include "pipes/messagepipes.h"
|
||||
#include "availablechannelorfeature.h"
|
||||
#include "export.h"
|
||||
|
||||
class ChannelAPI;
|
||||
class Feature;
|
||||
|
||||
// Utility class to help keeping track of list of available channels or features and optionally register pipes to them
|
||||
class SDRBASE_API AvailableChannelOrFeatureHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
// Use this constructor to just keep track of available channels and features with specified URIs and kinds
|
||||
AvailableChannelOrFeatureHandler(QStringList uris, const QString& kinds = "RTMF") :
|
||||
m_uris(uris),
|
||||
m_kinds(kinds)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
// Use this constructor to keep track of available channels and features with specified URIs and kinds and register pipes with the given names to them
|
||||
AvailableChannelOrFeatureHandler(QStringList uris, QStringList pipeNames, const QString& kinds = "RTMF") :
|
||||
m_uris(uris),
|
||||
m_pipeNames(pipeNames),
|
||||
m_kinds(kinds)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void scanAvailableChannelsAndFeatures();
|
||||
|
||||
const AvailableChannelOrFeatureList& getAvailableChannelOrFeatureList() const {
|
||||
return m_availableChannelOrFeatureList;
|
||||
}
|
||||
|
||||
QObject* registerPipes(const QString& longIdFrom, QObject* to, const QStringList& pipeNames);
|
||||
void deregisterPipes(QObject* from, QObject* to, const QStringList& pipeNames);
|
||||
|
||||
private:
|
||||
|
||||
AvailableChannelOrFeatureList m_availableChannelOrFeatureList;
|
||||
|
||||
QStringList m_uris; //!< URIs of channels/features we want to create a list for
|
||||
QStringList m_pipeNames; //!< List of pipe names to register
|
||||
QString m_kinds;
|
||||
|
||||
void init();
|
||||
void registerPipe(const QString& pipeName, QObject *channelOrFeature);
|
||||
|
||||
private slots:
|
||||
|
||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleChannelRemoved(int deviceSetIndex, ChannelAPI *channel);
|
||||
void handleStreamIndexChanged(int streamIndex);
|
||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
||||
void handleFeatureRemoved(int featureSetIndex, Feature *feature);
|
||||
|
||||
signals:
|
||||
void channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo); //!< Emitted when list of channels or features has changed
|
||||
void messageEnqueued(MessageQueue *messageQueue); //!< Emitted when message enqueued to a pipe
|
||||
|
||||
};
|
||||
|
||||
#endif // SDRBASE_AVAILABLECHANNELORFEATUREHANDLER_H_
|
@ -436,9 +436,9 @@ void MainCore::updateWakeLock()
|
||||
}
|
||||
#endif
|
||||
|
||||
QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableChannels(const QStringList& uris)
|
||||
AvailableChannelOrFeatureList MainCore::getAvailableChannels(const QStringList& uris)
|
||||
{
|
||||
QList<AvailableChannelOrFeature> list;
|
||||
AvailableChannelOrFeatureList list;
|
||||
|
||||
for (const auto deviceSet : m_deviceSets)
|
||||
{
|
||||
@ -467,9 +467,9 @@ QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableChannels(const
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableFeatures(const QStringList& uris)
|
||||
AvailableChannelOrFeatureList MainCore::getAvailableFeatures(const QStringList& uris)
|
||||
{
|
||||
QList<AvailableChannelOrFeature> list;
|
||||
AvailableChannelOrFeatureList list;
|
||||
std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
|
||||
|
||||
for (const auto& featureSet : featureSets)
|
||||
@ -496,37 +496,18 @@ QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableFeatures(const
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableChannelsAndFeatures(const QStringList& uris)
|
||||
AvailableChannelOrFeatureList MainCore::getAvailableChannelsAndFeatures(const QStringList& uris, const QString& kinds)
|
||||
{
|
||||
QList<AvailableChannelOrFeature> list;
|
||||
AvailableChannelOrFeatureList list;
|
||||
|
||||
list.append(getAvailableChannels(uris));
|
||||
list.append(getAvailableFeatures(uris));
|
||||
if (kinds != "F") {
|
||||
list.append(getAvailableChannels(uris));
|
||||
}
|
||||
if (kinds.contains("F")) {
|
||||
list.append(getAvailableFeatures(uris));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
QObject *MainCore::getAvailableChannelOrFeatureById(const QString& id, const QList<AvailableChannelOrFeature>& list)
|
||||
{
|
||||
for (const auto& item : list)
|
||||
{
|
||||
if (item.getId() == id) {
|
||||
return item.m_object;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QObject *MainCore::getAvailableChannelOrFeatureByLongId(const QString& longId, const QList<AvailableChannelOrFeature>& list)
|
||||
{
|
||||
for (const auto& item : list)
|
||||
{
|
||||
if (item.getLongId() == longId) {
|
||||
return item.m_object;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QChar MainCore::getDeviceSetTypeId(const DeviceSet* deviceSet)
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "pipes/messagepipes.h"
|
||||
#include "pipes/datapipes.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "availablechannelorfeature.h"
|
||||
|
||||
class DeviceSet;
|
||||
class FeatureSet;
|
||||
@ -908,39 +909,10 @@ public:
|
||||
// Position
|
||||
const QGeoPositionInfo& getPosition() const;
|
||||
|
||||
struct AvailableChannelOrFeature
|
||||
{
|
||||
QChar m_kind; //!< 'R' or 'T' for channel, 'M' for MIMO channel, 'F' for feature as from MainCore::getDeviceSetTypeId
|
||||
int m_superIndex; //!< Device Set index or Feature Set index
|
||||
int m_index; //!< Channel or Feature index
|
||||
int m_streamIndex; //!< For MIMO channels only
|
||||
QString m_type; //!< Plugin type (E.g. NFMDemod)
|
||||
QObject *m_object; //!< Pointer to the object (ChannelAPI or Feature object)
|
||||
|
||||
AvailableChannelOrFeature() = default;
|
||||
AvailableChannelOrFeature(const AvailableChannelOrFeature&) = default;
|
||||
AvailableChannelOrFeature& operator=(const AvailableChannelOrFeature&) = default;
|
||||
bool operator==(const AvailableChannelOrFeature& a) const {
|
||||
return (m_kind == a.m_kind) && (m_superIndex == a.m_superIndex) && (m_index == a.m_index) && (m_type == a.m_type);
|
||||
}
|
||||
QString getId() const { // Eg: "R3:4"
|
||||
QString id = QString("%1%2:%3").arg(m_kind).arg(m_superIndex).arg(m_index);
|
||||
if (m_kind == "M") {
|
||||
id.append(QString(".%1").arg(m_streamIndex));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
QString getLongId() const { // Eg: "F0:1 StarTracker"
|
||||
return QString("%1 %2").arg(getId()).arg(m_type);
|
||||
}
|
||||
};
|
||||
|
||||
// Use QList so ordered numerically
|
||||
QList<AvailableChannelOrFeature> getAvailableChannels(const QStringList& uris); // Get hash of available channels with given URIs or all if empty list. Hash hey is Id
|
||||
QList<AvailableChannelOrFeature> getAvailableFeatures(const QStringList& uris); // Get hash of available features with given URIs or all if empty list. Hash key is Id
|
||||
QList<AvailableChannelOrFeature> getAvailableChannelsAndFeatures(const QStringList& uris); // Get hash of available channels and features with given URIs or all if empty list. Hash key is Id
|
||||
static QObject *getAvailableChannelOrFeatureById(const QString& id, const QList<AvailableChannelOrFeature>& list);
|
||||
static QObject *getAvailableChannelOrFeatureByLongId(const QString& longId, const QList<AvailableChannelOrFeature>& list);
|
||||
// Lists of available channels and features. List should be ordered by indexes. Plugins should use AvailableChannelOrFeatureHandler to maintain this list
|
||||
AvailableChannelOrFeatureList getAvailableChannels(const QStringList& uris); // Get list of available channels with given URIs or all if empty list.
|
||||
AvailableChannelOrFeatureList getAvailableFeatures(const QStringList& uris); // Get list of available features with given URIs or all if empty list.
|
||||
AvailableChannelOrFeatureList getAvailableChannelsAndFeatures(const QStringList& uris, const QString& kinds); // Get list of available channels and features with given URIs or all if empty list.
|
||||
|
||||
// Ids
|
||||
QChar getDeviceSetTypeId(const DeviceSet* deviceSet); //!< Get Type Id (E.g. 'R', 'T' or 'M') for the given device set
|
||||
|
Loading…
Reference in New Issue
Block a user