mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-24 11:12:27 -04: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_basebandSink(nullptr),
|
||||||
m_running(false),
|
m_running(false),
|
||||||
m_basebandSampleRate(0),
|
m_basebandSampleRate(0),
|
||||||
|
m_availableChannelHandler({}),
|
||||||
m_scanDeviceSetIndex(0),
|
m_scanDeviceSetIndex(0),
|
||||||
m_scanChannelIndex(0),
|
m_scanChannelIndex(0),
|
||||||
m_state(IDLE),
|
m_state(IDLE),
|
||||||
@ -95,19 +96,8 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) :
|
|||||||
|
|
||||||
start();
|
start();
|
||||||
|
|
||||||
scanAvailableChannels();
|
QObject::connect(&m_availableChannelHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &FreqScanner::channelsChanged);
|
||||||
QObject::connect(
|
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::channelAdded,
|
|
||||||
this,
|
|
||||||
&FreqScanner::handleChannelAdded
|
|
||||||
);
|
|
||||||
QObject::connect(
|
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::channelRemoved,
|
|
||||||
this,
|
|
||||||
&FreqScanner::handleChannelRemoved
|
|
||||||
);
|
|
||||||
|
|
||||||
m_timeoutTimer.callOnTimeout(this, &FreqScanner::timeout);
|
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->removeChannelSink(this, m_settings.m_streamIndex);
|
||||||
m_deviceAPI->addChannelSink(this, settings.m_streamIndex);
|
m_deviceAPI->addChannelSink(this, settings.m_streamIndex);
|
||||||
m_deviceAPI->addChannelSinkAPI(this);
|
m_deviceAPI->addChannelSinkAPI(this);
|
||||||
scanAvailableChannels(); // re-scan
|
//FIXME:scanAvailableChannels(); // re-scan
|
||||||
emit streamIndexChanged(settings.m_streamIndex);
|
emit streamIndexChanged(settings.m_streamIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1116,186 +1106,18 @@ void FreqScanner::handleIndexInDeviceSetChanged(int index)
|
|||||||
m_basebandSink->setFifoLabel(fifoLabel);
|
m_basebandSink->setFifoLabel(fifoLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreqScanner::scanAvailableChannels()
|
void FreqScanner::channelsChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||||
{
|
{
|
||||||
m_availableChannels.clear();
|
m_availableChannels = m_availableChannelHandler.getAvailableChannelOrFeatureList();
|
||||||
|
notifyUpdateChannels(renameFrom, renameTo);
|
||||||
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 =
|
void FreqScanner::notifyUpdateChannels(const QStringList& renameFrom, const QStringList& renameTo)
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
if (getMessageQueueToGUI())
|
if (getMessageQueueToGUI())
|
||||||
{
|
{
|
||||||
MsgReportChannels* msgToGUI = MsgReportChannels::create();
|
MsgReportChannels* msgToGUI = MsgReportChannels::create(renameFrom, renameTo);
|
||||||
QList<FreqScannerSettings::AvailableChannel>& msgChannels = msgToGUI->getChannels();
|
msgToGUI->getChannels() = m_availableChannels;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
getMessageQueueToGUI()->push(msgToGUI);
|
getMessageQueueToGUI()->push(msgToGUI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "dsp/basebandsamplesink.h"
|
#include "dsp/basebandsamplesink.h"
|
||||||
#include "channel/channelapi.h"
|
#include "channel/channelapi.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
|
|
||||||
#include "freqscannerbaseband.h"
|
#include "freqscannerbaseband.h"
|
||||||
#include "freqscannersettings.h"
|
#include "freqscannersettings.h"
|
||||||
@ -71,17 +72,23 @@ public:
|
|||||||
|
|
||||||
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() {
|
static MsgReportChannels* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||||
return new MsgReportChannels();
|
return new MsgReportChannels(renameFrom, renameTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<FreqScannerSettings::AvailableChannel> m_channels;
|
AvailableChannelOrFeatureList m_channels;
|
||||||
|
QStringList m_renameFrom;
|
||||||
|
QStringList m_renameTo;
|
||||||
|
|
||||||
MsgReportChannels() :
|
MsgReportChannels(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||||
Message()
|
Message(),
|
||||||
|
m_renameFrom(renameFrom),
|
||||||
|
m_renameTo(renameTo)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -369,7 +376,8 @@ private:
|
|||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
QNetworkRequest m_networkRequest;
|
QNetworkRequest m_networkRequest;
|
||||||
|
|
||||||
QHash<ChannelAPI*, FreqScannerSettings::AvailableChannel> m_availableChannels;
|
AvailableChannelOrFeatureList m_availableChannels;
|
||||||
|
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||||
|
|
||||||
unsigned int m_scanDeviceSetIndex;
|
unsigned int m_scanDeviceSetIndex;
|
||||||
unsigned int m_scanChannelIndex;
|
unsigned int m_scanChannelIndex;
|
||||||
@ -402,8 +410,8 @@ private:
|
|||||||
);
|
);
|
||||||
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
|
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
|
||||||
|
|
||||||
void scanAvailableChannels();
|
//void scanAvailableChannels();
|
||||||
void notifyUpdateChannels();
|
void notifyUpdateChannels(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void startScan();
|
void startScan();
|
||||||
void stopScan();
|
void stopScan();
|
||||||
void initScan();
|
void initScan();
|
||||||
@ -416,9 +424,7 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
void networkManagerFinished(QNetworkReply *reply);
|
void networkManagerFinished(QNetworkReply *reply);
|
||||||
void handleIndexInDeviceSetChanged(int index);
|
void handleIndexInDeviceSetChanged(int index);
|
||||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI* channel);
|
void channelsChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void handleChannelRemoved(int deviceSetIndex, ChannelAPI* channel);
|
|
||||||
void handleChannelStreamIndexChanged(int streamIndex, ChannelAPI* channel);
|
|
||||||
void timeout();
|
void timeout();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -118,8 +118,7 @@ bool FreqScannerGUI::handleMessage(const Message& message)
|
|||||||
else if (FreqScanner::MsgReportChannels::match(message))
|
else if (FreqScanner::MsgReportChannels::match(message))
|
||||||
{
|
{
|
||||||
FreqScanner::MsgReportChannels& report = (FreqScanner::MsgReportChannels&)message;
|
FreqScanner::MsgReportChannels& report = (FreqScanner::MsgReportChannels&)message;
|
||||||
m_availableChannels = report.getChannels();
|
updateChannelsList(report.getChannels(), report.getRenameFrom(), report.getRenameTo());
|
||||||
updateChannelsList(m_availableChannels);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (FreqScanner::MsgStatus::match(message))
|
else if (FreqScanner::MsgStatus::match(message))
|
||||||
@ -212,7 +211,7 @@ bool FreqScannerGUI::handleMessage(const Message& message)
|
|||||||
return false;
|
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->blockSignals(true);
|
||||||
combo->clear();
|
combo->clear();
|
||||||
@ -223,17 +222,8 @@ void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QList<FreqScann
|
|||||||
for (const auto& channel : channels)
|
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)
|
// 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()))
|
if ((channel.m_superIndex == m_freqScanner->getDeviceSetIndex()) && (channel.m_index != m_freqScanner->getIndexInDeviceSet())) {
|
||||||
{
|
combo->addItem(channel.getId());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,8 +240,29 @@ void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QList<FreqScann
|
|||||||
combo->blockSignals(false);
|
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);
|
updateChannelsCombo(ui->channels, channels, m_settings.m_channel, false);
|
||||||
|
|
||||||
for (int row = 0; row < ui->table->rowCount(); row++)
|
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)
|
void FreqScannerGUI::applySettings(const QStringList& settingsKeys, bool force)
|
||||||
{
|
{
|
||||||
|
m_settingsKeys.append(settingsKeys);
|
||||||
if (m_doApplySettings)
|
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_freqScanner->getInputMessageQueue()->push(message);
|
||||||
|
m_settingsKeys.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ private:
|
|||||||
ChannelMarker m_channelMarker;
|
ChannelMarker m_channelMarker;
|
||||||
RollupState m_rollupState;
|
RollupState m_rollupState;
|
||||||
FreqScannerSettings m_settings;
|
FreqScannerSettings m_settings;
|
||||||
|
QList<QString> m_settingsKeys;
|
||||||
qint64 m_deviceCenterFrequency;
|
qint64 m_deviceCenterFrequency;
|
||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ private:
|
|||||||
|
|
||||||
QMenu *m_menu;
|
QMenu *m_menu;
|
||||||
|
|
||||||
QList<FreqScannerSettings::AvailableChannel> m_availableChannels;
|
AvailableChannelOrFeatureList m_availableChannels;
|
||||||
|
|
||||||
explicit FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
explicit FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||||
virtual ~FreqScannerGUI();
|
virtual ~FreqScannerGUI();
|
||||||
@ -98,8 +99,8 @@ private:
|
|||||||
void addRow(const FreqScannerSettings::FrequencySettings& frequencySettings);
|
void addRow(const FreqScannerSettings::FrequencySettings& frequencySettings);
|
||||||
void updateAnnotation(int row);
|
void updateAnnotation(int row);
|
||||||
void updateAnnotations();
|
void updateAnnotations();
|
||||||
void updateChannelsCombo(QComboBox *combo, const QList<FreqScannerSettings::AvailableChannel>& channels, const QString& channel, bool empty);
|
void updateChannelsCombo(QComboBox *combo, const AvailableChannelOrFeatureList& channels, const QString& channel, bool empty);
|
||||||
void updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels);
|
void updateChannelsList(const AvailableChannelOrFeatureList& channels, const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void setAllEnabled(bool enable);
|
void setAllEnabled(bool enable);
|
||||||
|
|
||||||
void leaveEvent(QEvent*);
|
void leaveEvent(QEvent*);
|
||||||
|
@ -31,17 +31,6 @@ class ChannelAPI;
|
|||||||
|
|
||||||
struct FreqScannerSettings
|
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 {
|
struct FrequencySettings {
|
||||||
qint64 m_frequency;
|
qint64 m_frequency;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. //
|
// 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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -70,7 +70,9 @@ RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) :
|
|||||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
||||||
m_deviceAPI(deviceAPI),
|
m_deviceAPI(deviceAPI),
|
||||||
m_basebandSampleRate(0),
|
m_basebandSampleRate(0),
|
||||||
m_sweeping(false)
|
m_sweeping(false),
|
||||||
|
m_availableFeatureHandler({"sdrangel.feature.startracker"}, QStringList{"startracker.target"}),
|
||||||
|
m_availableRotatorHandler({"sdrangel.feature.gs232controller"})
|
||||||
{
|
{
|
||||||
qDebug("RadioAstronomy::RadioAstronomy");
|
qDebug("RadioAstronomy::RadioAstronomy");
|
||||||
setObjectName(m_channelId);
|
setObjectName(m_channelId);
|
||||||
@ -105,17 +107,26 @@ RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) :
|
|||||||
&RadioAstronomy::handleIndexInDeviceSetChanged
|
&RadioAstronomy::handleIndexInDeviceSetChanged
|
||||||
);
|
);
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
MainCore::instance(),
|
&m_availableFeatureHandler,
|
||||||
&MainCore::featureAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&RadioAstronomy::handleFeatureAdded
|
&RadioAstronomy::handleFeatureMessageQueue
|
||||||
);
|
);
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
MainCore::instance(),
|
&m_availableFeatureHandler,
|
||||||
&MainCore::featureRemoved,
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
this,
|
this,
|
||||||
&RadioAstronomy::handleFeatureRemoved
|
&RadioAstronomy::featuresChanged
|
||||||
);
|
);
|
||||||
|
m_availableFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||||
|
|
||||||
|
QObject::connect(
|
||||||
|
&m_availableRotatorHandler,
|
||||||
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
|
this,
|
||||||
|
&RadioAstronomy::rotatorsChanged
|
||||||
|
);
|
||||||
|
m_availableRotatorHandler.scanAvailableChannelsAndFeatures();
|
||||||
|
|
||||||
m_sweepTimer.setSingleShot(true);
|
m_sweepTimer.setSingleShot(true);
|
||||||
}
|
}
|
||||||
@ -123,17 +134,20 @@ RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) :
|
|||||||
RadioAstronomy::~RadioAstronomy()
|
RadioAstronomy::~RadioAstronomy()
|
||||||
{
|
{
|
||||||
qDebug("RadioAstronomy::~RadioAstronomy");
|
qDebug("RadioAstronomy::~RadioAstronomy");
|
||||||
QObject::disconnect(
|
QObject::disconnect(&m_availableFeatureHandler,
|
||||||
MainCore::instance(),
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
&MainCore::featureRemoved,
|
|
||||||
this,
|
this,
|
||||||
&RadioAstronomy::handleFeatureRemoved
|
&RadioAstronomy::handleFeatureMessageQueue
|
||||||
);
|
);
|
||||||
QObject::disconnect(
|
QObject::disconnect(&m_availableFeatureHandler,
|
||||||
MainCore::instance(),
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
&MainCore::featureAdded,
|
|
||||||
this,
|
this,
|
||||||
&RadioAstronomy::handleFeatureAdded
|
&RadioAstronomy::featuresChanged
|
||||||
|
);
|
||||||
|
QObject::disconnect(&m_availableRotatorHandler,
|
||||||
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
|
this,
|
||||||
|
&RadioAstronomy::rotatorsChanged
|
||||||
);
|
);
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
m_networkManager,
|
m_networkManager,
|
||||||
@ -194,8 +208,6 @@ void RadioAstronomy::start()
|
|||||||
m_basebandSink->getInputMessageQueue()->push(new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency));
|
m_basebandSink->getInputMessageQueue()->push(new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency));
|
||||||
m_basebandSink->getInputMessageQueue()->push(RadioAstronomyBaseband::MsgConfigureRadioAstronomyBaseband::create(m_settings, true));
|
m_basebandSink->getInputMessageQueue()->push(RadioAstronomyBaseband::MsgConfigureRadioAstronomyBaseband::create(m_settings, true));
|
||||||
m_worker->getInputMessageQueue()->push(RadioAstronomyWorker::MsgConfigureRadioAstronomyWorker::create(m_settings, true));
|
m_worker->getInputMessageQueue()->push(RadioAstronomyWorker::MsgConfigureRadioAstronomyWorker::create(m_settings, true));
|
||||||
|
|
||||||
scanAvailableFeatures();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadioAstronomy::stop()
|
void RadioAstronomy::stop()
|
||||||
@ -330,7 +342,8 @@ bool RadioAstronomy::handleMessage(const Message& cmd)
|
|||||||
}
|
}
|
||||||
else if (MsgScanAvailableFeatures::match(cmd))
|
else if (MsgScanAvailableFeatures::match(cmd))
|
||||||
{
|
{
|
||||||
scanAvailableFeatures();
|
notifyUpdateFeatures({}, {});
|
||||||
|
notifyUpdateRotators({}, {});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -753,22 +766,14 @@ void RadioAstronomy::applySettings(const RadioAstronomySettings& settings, bool
|
|||||||
{
|
{
|
||||||
if (!settings.m_starTracker.isEmpty())
|
if (!settings.m_starTracker.isEmpty())
|
||||||
{
|
{
|
||||||
Feature *feature = nullptr;
|
int index = m_availableFeatures.indexOfLongId(settings.m_starTracker);
|
||||||
|
if (index >= 0)
|
||||||
for (const auto& fval : m_availableFeatures)
|
|
||||||
{
|
{
|
||||||
QString starTrackerText = tr("F%1:%2 %3").arg(fval.m_featureSetIndex).arg(fval.m_featureIndex).arg(fval.m_type);
|
m_selectedPipe = m_availableFeatures[index].m_object;
|
||||||
|
}
|
||||||
if (settings.m_starTracker == starTrackerText)
|
else
|
||||||
{
|
{
|
||||||
feature = m_availableFeatures.key(fval);
|
m_selectedPipe = nullptr;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (feature) {
|
|
||||||
m_selectedPipe = feature;
|
|
||||||
} else {
|
|
||||||
qDebug() << "RadioAstronomy::applySettings: No plugin corresponding to target " << settings.m_starTracker;
|
qDebug() << "RadioAstronomy::applySettings: No plugin corresponding to target " << settings.m_starTracker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1246,145 +1251,39 @@ void RadioAstronomy::handleIndexInDeviceSetChanged(int index)
|
|||||||
m_basebandSink->setFifoLabel(fifoLabel);
|
m_basebandSink->setFifoLabel(fifoLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadioAstronomy::scanAvailableFeatures()
|
void RadioAstronomy::featuresChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||||
{
|
{
|
||||||
qDebug("RadioAstronomy::scanAvailableFeatures");
|
m_availableFeatures = m_availableFeatureHandler.getAvailableChannelOrFeatureList();
|
||||||
MainCore *mainCore = MainCore::instance();
|
notifyUpdateFeatures(renameFrom, renameTo);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RadioAstronomy::notifyUpdateFeatures()
|
void RadioAstronomy::notifyUpdateFeatures(const QStringList& renameFrom, const QStringList& renameTo)
|
||||||
{
|
{
|
||||||
if (getMessageQueueToGUI())
|
if (getMessageQueueToGUI())
|
||||||
{
|
{
|
||||||
MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create();
|
MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create(renameFrom, renameTo);
|
||||||
msg->getFeatures() = m_availableFeatures.values();
|
msg->getFeatures() = m_availableFeatures;
|
||||||
getMessageQueueToGUI()->push(msg);
|
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())
|
if (getMessageQueueToGUI())
|
||||||
{
|
{
|
||||||
MsgReportAvailableRotators *msg = MsgReportAvailableRotators::create();
|
MsgReportAvailableRotators *msg = MsgReportAvailableRotators::create(renameFrom, renameTo);
|
||||||
msg->getFeatures() = m_rotators.values();
|
msg->getFeatures() = m_rotators;
|
||||||
getMessageQueueToGUI()->push(msg);
|
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)
|
void RadioAstronomy::handleFeatureMessageQueue(MessageQueue* messageQueue)
|
||||||
{
|
{
|
||||||
Message* message;
|
Message* message;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. //
|
// 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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include "dsp/basebandsamplesink.h"
|
#include "dsp/basebandsamplesink.h"
|
||||||
#include "channel/channelapi.h"
|
#include "channel/channelapi.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
|
|
||||||
#include "radioastronomybaseband.h"
|
#include "radioastronomybaseband.h"
|
||||||
#include "radioastronomysettings.h"
|
#include "radioastronomysettings.h"
|
||||||
@ -329,17 +330,23 @@ public:
|
|||||||
MESSAGE_CLASS_DECLARATION
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
public:
|
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() {
|
static MsgReportAvailableFeatures* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||||
return new MsgReportAvailableFeatures();
|
return new MsgReportAvailableFeatures(renameFrom, renameTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
AvailableChannelOrFeatureList m_availableFeatures;
|
||||||
|
QStringList m_renameFrom;
|
||||||
|
QStringList m_renameTo;
|
||||||
|
|
||||||
MsgReportAvailableFeatures() :
|
MsgReportAvailableFeatures(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||||
Message()
|
Message(),
|
||||||
|
m_renameFrom(renameFrom),
|
||||||
|
m_renameTo(renameTo)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -347,17 +354,24 @@ public:
|
|||||||
MESSAGE_CLASS_DECLARATION
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
public:
|
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:
|
private:
|
||||||
QList<RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
AvailableChannelOrFeatureList m_availableFeatures;
|
||||||
|
QStringList m_renameFrom;
|
||||||
|
QStringList m_renameTo;
|
||||||
|
|
||||||
MsgReportAvailableRotators() :
|
MsgReportAvailableRotators(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||||
Message()
|
Message(),
|
||||||
|
m_renameFrom(renameFrom),
|
||||||
|
m_renameTo(renameTo)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -448,8 +462,10 @@ private:
|
|||||||
int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
|
int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
|
||||||
qint64 m_centerFrequency;
|
qint64 m_centerFrequency;
|
||||||
|
|
||||||
QHash<Feature*, RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
AvailableChannelOrFeatureHandler m_availableFeatureHandler;
|
||||||
QHash<Feature*, RadioAstronomySettings::AvailableFeature> m_rotators;
|
AvailableChannelOrFeatureList m_availableFeatures;
|
||||||
|
AvailableChannelOrFeatureHandler m_availableRotatorHandler;
|
||||||
|
AvailableChannelOrFeatureList m_rotators;
|
||||||
QObject *m_selectedPipe;
|
QObject *m_selectedPipe;
|
||||||
|
|
||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
@ -482,9 +498,8 @@ private:
|
|||||||
void sweepStart();
|
void sweepStart();
|
||||||
void startCal(bool hot);
|
void startCal(bool hot);
|
||||||
void calComplete(MsgCalComplete* report);
|
void calComplete(MsgCalComplete* report);
|
||||||
void scanAvailableFeatures();
|
void notifyUpdateFeatures(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void notifyUpdateFeatures();
|
void notifyUpdateRotators(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void notifyUpdateRotators();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void networkManagerFinished(QNetworkReply *reply);
|
void networkManagerFinished(QNetworkReply *reply);
|
||||||
@ -496,9 +511,8 @@ private slots:
|
|||||||
void sweepNext();
|
void sweepNext();
|
||||||
void sweepComplete();
|
void sweepComplete();
|
||||||
void handleIndexInDeviceSetChanged(int index);
|
void handleIndexInDeviceSetChanged(int index);
|
||||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
void featuresChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void handleFeatureRemoved(int featureSetIndex, Feature *feature);
|
void rotatorsChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
|
||||||
void handleFeatureMessageQueue(MessageQueue* messageQueue);
|
void handleFeatureMessageQueue(MessageQueue* messageQueue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
// 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 //
|
// 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 //
|
// 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->blockSignals(true);
|
||||||
ui->starTracker->clear();
|
ui->starTracker->clear();
|
||||||
|
|
||||||
for (const auto& feature : m_availableFeatures) {
|
for (const auto& feature : availableFeatures) {
|
||||||
ui->starTracker->addItem(tr("F%1:%2 %3").arg(feature.m_featureSetIndex).arg(feature.m_featureIndex).arg(feature.m_type));
|
ui->starTracker->addItem(feature.getLongId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentText.isEmpty())
|
int idx = ui->starTracker->findText(m_settings.m_starTracker);
|
||||||
{
|
if (idx >= 0) {
|
||||||
if (m_availableFeatures.size() > 0) {
|
ui->starTracker->setCurrentIndex(idx);
|
||||||
|
} else {
|
||||||
ui->starTracker->setCurrentIndex(0);
|
ui->starTracker->setCurrentIndex(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->starTracker->setCurrentIndex(ui->starTracker->findText(currentText));
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->starTracker->blockSignals(false);
|
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;
|
m_settings.m_starTracker = newText;
|
||||||
applySettings();
|
applySettings();
|
||||||
@ -970,8 +972,7 @@ bool RadioAstronomyGUI::handleMessage(const Message& message)
|
|||||||
{
|
{
|
||||||
qDebug("RadioAstronomyGUI::handleMessage: MsgReportAvailableFeatures");
|
qDebug("RadioAstronomyGUI::handleMessage: MsgReportAvailableFeatures");
|
||||||
RadioAstronomy::MsgReportAvailableFeatures& report = (RadioAstronomy::MsgReportAvailableFeatures&) message;
|
RadioAstronomy::MsgReportAvailableFeatures& report = (RadioAstronomy::MsgReportAvailableFeatures&) message;
|
||||||
m_availableFeatures = report.getFeatures();
|
updateAvailableFeatures(report.getFeatures(), report.getRenameFrom(), report.getRenameTo());
|
||||||
updateAvailableFeatures();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (MainCore::MsgStarTrackerTarget::match(message))
|
else if (MainCore::MsgStarTrackerTarget::match(message))
|
||||||
@ -1063,7 +1064,7 @@ bool RadioAstronomyGUI::handleMessage(const Message& message)
|
|||||||
else if (RadioAstronomy::MsgReportAvailableRotators::match(message))
|
else if (RadioAstronomy::MsgReportAvailableRotators::match(message))
|
||||||
{
|
{
|
||||||
RadioAstronomy::MsgReportAvailableRotators& report = (RadioAstronomy::MsgReportAvailableRotators&) message;
|
RadioAstronomy::MsgReportAvailableRotators& report = (RadioAstronomy::MsgReportAvailableRotators&) message;
|
||||||
updateRotatorList(report.getFeatures());
|
updateRotatorList(report.getFeatures(), report.getRenameFrom(), report.getRenameTo());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1901,11 +1902,11 @@ void RadioAstronomyGUI::on_loadSpectrumData_clicked()
|
|||||||
|
|
||||||
void RadioAstronomyGUI::on_powerTable_cellDoubleClicked(int row, int column)
|
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
|
// Display target in Star Tracker
|
||||||
QList<ObjectPipe*> starTrackerPipes;
|
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)
|
for (const auto& pipe : starTrackerPipes)
|
||||||
{
|
{
|
||||||
@ -2604,17 +2605,22 @@ void RadioAstronomyGUI::tick()
|
|||||||
m_tickCount++;
|
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
|
// Update list of rotators
|
||||||
ui->rotator->blockSignals(true);
|
ui->rotator->blockSignals(true);
|
||||||
ui->rotator->clear();
|
ui->rotator->clear();
|
||||||
ui->rotator->addItem("None");
|
ui->rotator->addItem("None");
|
||||||
|
|
||||||
for (const auto& rotator : rotators)
|
for (const auto& rotator : rotators) {
|
||||||
{
|
ui->rotator->addItem(rotator.getLongId());
|
||||||
QString name = QString("F%1:%2 %3").arg(rotator.m_featureSetIndex).arg(rotator.m_featureIndex).arg(rotator.m_type);
|
|
||||||
ui->rotator->addItem(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotator feature can be created after this plugin, so select it
|
// 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
|
// Send to Star Tracker
|
||||||
QList<ObjectPipe*> starTrackerPipes;
|
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)
|
for (const auto& pipe : starTrackerPipes)
|
||||||
{
|
{
|
||||||
@ -4794,7 +4800,7 @@ void RadioAstronomyGUI::on_spectrumIndex_valueChanged(int value)
|
|||||||
|
|
||||||
// Display target in Star Tracker
|
// Display target in Star Tracker
|
||||||
QList<ObjectPipe*> starTrackerPipes;
|
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)
|
for (const auto& pipe : starTrackerPipes)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
// 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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -235,7 +235,6 @@ private:
|
|||||||
RollupState m_rollupState;
|
RollupState m_rollupState;
|
||||||
RadioAstronomySettings m_settings;
|
RadioAstronomySettings m_settings;
|
||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
QList<RadioAstronomySettings::AvailableFeature> m_availableFeatures;
|
|
||||||
|
|
||||||
int m_basebandSampleRate;
|
int m_basebandSampleRate;
|
||||||
quint64 m_centerFrequency;
|
quint64 m_centerFrequency;
|
||||||
@ -351,8 +350,8 @@ private:
|
|||||||
void displaySettings();
|
void displaySettings();
|
||||||
void displaySpectrumLineFrequency();
|
void displaySpectrumLineFrequency();
|
||||||
void displayRunModeSettings();
|
void displayRunModeSettings();
|
||||||
void updateAvailableFeatures();
|
void updateAvailableFeatures(const AvailableChannelOrFeatureList& availableFeatures, const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void updateRotatorList(const QList<RadioAstronomySettings::AvailableFeature>& rotators);
|
void updateRotatorList(const AvailableChannelOrFeatureList& rotators, const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
bool handleMessage(const Message& message);
|
bool handleMessage(const Message& message);
|
||||||
void makeUIConnections();
|
void makeUIConnections();
|
||||||
void updateAbsoluteCenterFrequency();
|
void updateAbsoluteCenterFrequency();
|
||||||
|
@ -23,14 +23,6 @@
|
|||||||
#include "settings/serializable.h"
|
#include "settings/serializable.h"
|
||||||
#include "radioastronomysettings.h"
|
#include "radioastronomysettings.h"
|
||||||
|
|
||||||
const QStringList RadioAstronomySettings::m_pipeTypes = {
|
|
||||||
QStringLiteral("StarTracker")
|
|
||||||
};
|
|
||||||
|
|
||||||
const QStringList RadioAstronomySettings::m_pipeURIs = {
|
|
||||||
QStringLiteral("sdrangel.feature.startracker")
|
|
||||||
};
|
|
||||||
|
|
||||||
RadioAstronomySettings::RadioAstronomySettings() :
|
RadioAstronomySettings::RadioAstronomySettings() :
|
||||||
m_channelMarker(nullptr),
|
m_channelMarker(nullptr),
|
||||||
m_rollupState(nullptr)
|
m_rollupState(nullptr)
|
||||||
|
@ -35,20 +35,6 @@ class Serializable;
|
|||||||
|
|
||||||
struct RadioAstronomySettings
|
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_inputFrequencyOffset;
|
||||||
int m_sampleRate;
|
int m_sampleRate;
|
||||||
int m_rfBandwidth;
|
int m_rfBandwidth;
|
||||||
@ -244,9 +230,6 @@ struct RadioAstronomySettings
|
|||||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||||
QByteArray serialize() const;
|
QByteArray serialize() const;
|
||||||
bool deserialize(const QByteArray& data);
|
bool deserialize(const QByteArray& data);
|
||||||
|
|
||||||
static const QStringList m_pipeTypes;
|
|
||||||
static const QStringList m_pipeURIs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* INCLUDE_RADIOASTRONOMYSETTINGS_H */
|
#endif /* INCLUDE_RADIOASTRONOMYSETTINGS_H */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// 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 //
|
// 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 //
|
// 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";
|
const char* const AIS::m_featureId = "AIS";
|
||||||
|
|
||||||
AIS::AIS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
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);
|
qDebug("AIS::AIS: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||||
setObjectName(m_featureId);
|
setObjectName(m_featureId);
|
||||||
@ -54,23 +55,20 @@ AIS::AIS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
|||||||
this,
|
this,
|
||||||
&AIS::networkManagerFinished
|
&AIS::networkManagerFinished
|
||||||
);
|
);
|
||||||
scanAvailableChannels();
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
MainCore::instance(),
|
&m_availableChannelHandler,
|
||||||
&MainCore::channelAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&AIS::handleChannelAdded
|
&AIS::handleChannelMessageQueue);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AIS::~AIS()
|
AIS::~AIS()
|
||||||
{
|
{
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
MainCore::instance(),
|
&m_availableChannelHandler,
|
||||||
&MainCore::channelAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&AIS::handleChannelAdded
|
&AIS::handleChannelMessageQueue);
|
||||||
);
|
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
m_networkManager,
|
m_networkManager,
|
||||||
&QNetworkAccessManager::finished,
|
&QNetworkAccessManager::finished,
|
||||||
@ -362,90 +360,6 @@ void AIS::networkManagerFinished(QNetworkReply *reply)
|
|||||||
reply->deleteLater();
|
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)
|
void AIS::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||||
{
|
{
|
||||||
Message* message;
|
Message* message;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "feature/feature.h"
|
#include "feature/feature.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
|
|
||||||
#include "aissettings.h"
|
#include "aissettings.h"
|
||||||
|
|
||||||
@ -101,7 +102,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
AISSettings m_settings;
|
AISSettings m_settings;
|
||||||
QSet<ChannelAPI*> m_availableChannels;
|
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||||
|
AvailableChannelOrFeatureList m_availableChannels;
|
||||||
|
|
||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
QNetworkRequest m_networkRequest;
|
QNetworkRequest m_networkRequest;
|
||||||
@ -110,12 +112,9 @@ private:
|
|||||||
void stop();
|
void stop();
|
||||||
void applySettings(const AISSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
void applySettings(const AISSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const AISSettings& settings, bool force);
|
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const AISSettings& settings, bool force);
|
||||||
void scanAvailableChannels();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void networkManagerFinished(QNetworkReply *reply);
|
void networkManagerFinished(QNetworkReply *reply);
|
||||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
|
||||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
|
||||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
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> //
|
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// 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",
|
"tug_20m.glbe", "tug_30m_1.glbe", "tug_30m_2.glbe", "tug_30m_3.glbe",
|
||||||
"cargo_75m.glbe", "tanker_50m.glbe", "dredger_53m.glbe",
|
"cargo_75m.glbe", "tanker_50m.glbe", "dredger_53m.glbe",
|
||||||
"trawler_22m.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 = {
|
QStringList AISGUI::m_sailboatModels = {
|
||||||
@ -236,6 +236,7 @@ AISGUI::AISGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
|
|||||||
|
|
||||||
displaySettings();
|
displaySettings();
|
||||||
applySettings(true);
|
applySettings(true);
|
||||||
|
m_resizer.enableChildMouseTracking();
|
||||||
}
|
}
|
||||||
|
|
||||||
AISGUI::~AISGUI()
|
AISGUI::~AISGUI()
|
||||||
@ -845,14 +846,14 @@ void AISGUI::getImageAndModel(const QString &type, const QString &shipType, int
|
|||||||
{
|
{
|
||||||
vessel->m_model = "cargo_75m.glbe";
|
vessel->m_model = "cargo_75m.glbe";
|
||||||
}
|
}
|
||||||
else if (length < 200)
|
else /*if (length < 200)*/
|
||||||
{
|
{
|
||||||
vessel->m_model = "cargo_190m.glbe";
|
vessel->m_model = "cargo_190m.glbe";
|
||||||
}
|
}
|
||||||
else
|
/*else
|
||||||
{
|
{
|
||||||
vessel->m_model = "cargo_230m.glbe";
|
vessel->m_model = "cargo_230m.glbe";
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
else if (shipType == "Tanker")
|
else if (shipType == "Tanker")
|
||||||
{
|
{
|
||||||
@ -905,10 +906,10 @@ void AISGUI::getImageAndModel(const QString &type, const QString &shipType, int
|
|||||||
{
|
{
|
||||||
vessel->m_model = "speedboat_8m.glbe";
|
vessel->m_model = "speedboat_8m.glbe";
|
||||||
}
|
}
|
||||||
else if (length < 18)
|
/*else if (length < 18)
|
||||||
{
|
{
|
||||||
vessel->m_model = "yacht_10m.glbe";
|
vessel->m_model = "yacht_10m.glbe";
|
||||||
}
|
}*/
|
||||||
else if (length < 32)
|
else if (length < 32)
|
||||||
{
|
{
|
||||||
vessel->m_model = "yacht_20m.glbe";
|
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> //
|
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// 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) :
|
APRS::APRS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||||
m_thread(nullptr),
|
m_thread(nullptr),
|
||||||
m_worker(nullptr)
|
m_worker(nullptr),
|
||||||
|
m_availableChannelHandler(APRSSettings::m_pipeURIs, QStringList{"packets"})
|
||||||
{
|
{
|
||||||
qDebug("APRS::APRS: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
qDebug("APRS::APRS: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||||
setObjectName(m_featureId);
|
setObjectName(m_featureId);
|
||||||
@ -59,23 +60,31 @@ APRS::APRS(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
|||||||
this,
|
this,
|
||||||
&APRS::networkManagerFinished
|
&APRS::networkManagerFinished
|
||||||
);
|
);
|
||||||
scanAvailableChannels();
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
MainCore::instance(),
|
&m_availableChannelHandler,
|
||||||
&MainCore::channelAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&APRS::handleChannelAdded
|
&APRS::handleChannelMessageQueue);
|
||||||
);
|
QObject::connect(
|
||||||
|
&m_availableChannelHandler,
|
||||||
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
|
this,
|
||||||
|
&APRS::channelsChanged);
|
||||||
|
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
APRS::~APRS()
|
APRS::~APRS()
|
||||||
{
|
{
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
MainCore::instance(),
|
&m_availableChannelHandler,
|
||||||
&MainCore::channelAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&APRS::handleChannelAdded
|
&APRS::handleChannelMessageQueue);
|
||||||
);
|
QObject::disconnect(
|
||||||
|
&m_availableChannelHandler,
|
||||||
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
|
this,
|
||||||
|
&APRS::channelsChanged);
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
m_networkManager,
|
m_networkManager,
|
||||||
&QNetworkAccessManager::finished,
|
&QNetworkAccessManager::finished,
|
||||||
@ -858,6 +867,7 @@ void APRS::networkManagerFinished(QNetworkReply *reply)
|
|||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void APRS::scanAvailableChannels()
|
void APRS::scanAvailableChannels()
|
||||||
{
|
{
|
||||||
MainCore *mainCore = MainCore::instance();
|
MainCore *mainCore = MainCore::instance();
|
||||||
@ -905,18 +915,25 @@ void APRS::scanAvailableChannels()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void APRS::channelsChanged()
|
||||||
|
{
|
||||||
|
m_availableChannels = m_availableChannelHandler.getAvailableChannelOrFeatureList();
|
||||||
|
notifyUpdateChannels();
|
||||||
|
}
|
||||||
|
|
||||||
void APRS::notifyUpdateChannels()
|
void APRS::notifyUpdateChannels()
|
||||||
{
|
{
|
||||||
if (getMessageQueueToGUI())
|
if (getMessageQueueToGUI())
|
||||||
{
|
{
|
||||||
MsgReportAvailableChannels *msg = MsgReportAvailableChannels::create();
|
MsgReportAvailableChannels *msg = MsgReportAvailableChannels::create();
|
||||||
msg->getChannels() = m_availableChannels.values();
|
msg->getChannels() = m_availableChannels;
|
||||||
getMessageQueueToGUI()->push(msg);
|
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)",
|
qDebug("APRS::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)",
|
||||||
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel);
|
||||||
@ -964,7 +981,7 @@ void APRS::handleMessagePipeToBeDeleted(int reason, QObject* object)
|
|||||||
m_availableChannels.remove((ChannelAPI*) object);
|
m_availableChannels.remove((ChannelAPI*) object);
|
||||||
notifyUpdateChannels();
|
notifyUpdateChannels();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void APRS::handleChannelMessageQueue(MessageQueue* messageQueue)
|
void APRS::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "feature/feature.h"
|
#include "feature/feature.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
|
|
||||||
#include "aprssettings.h"
|
#include "aprssettings.h"
|
||||||
|
|
||||||
@ -104,14 +105,14 @@ public:
|
|||||||
MESSAGE_CLASS_DECLARATION
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QList<APRSSettings::AvailableChannel>& getChannels() { return m_availableChannels; }
|
AvailableChannelOrFeatureList& getChannels() { return m_availableChannels; }
|
||||||
|
|
||||||
static MsgReportAvailableChannels* create() {
|
static MsgReportAvailableChannels* create() {
|
||||||
return new MsgReportAvailableChannels();
|
return new MsgReportAvailableChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<APRSSettings::AvailableChannel> m_availableChannels;
|
AvailableChannelOrFeatureList m_availableChannels;
|
||||||
|
|
||||||
MsgReportAvailableChannels() :
|
MsgReportAvailableChannels() :
|
||||||
Message()
|
Message()
|
||||||
@ -160,7 +161,8 @@ private:
|
|||||||
QThread *m_thread;
|
QThread *m_thread;
|
||||||
APRSWorker *m_worker;
|
APRSWorker *m_worker;
|
||||||
APRSSettings m_settings;
|
APRSSettings m_settings;
|
||||||
QHash<ChannelAPI*, APRSSettings::AvailableChannel> m_availableChannels;
|
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||||
|
AvailableChannelOrFeatureList m_availableChannels;
|
||||||
|
|
||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
QNetworkRequest m_networkRequest;
|
QNetworkRequest m_networkRequest;
|
||||||
@ -169,14 +171,12 @@ private:
|
|||||||
void stop();
|
void stop();
|
||||||
void applySettings(const APRSSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
void applySettings(const APRSSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const APRSSettings& settings, bool force);
|
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const APRSSettings& settings, bool force);
|
||||||
void scanAvailableChannels();
|
|
||||||
void notifyUpdateChannels();
|
void notifyUpdateChannels();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void networkManagerFinished(QNetworkReply *reply);
|
void networkManagerFinished(QNetworkReply *reply);
|
||||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
|
||||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
|
||||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
||||||
|
void channelsChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDE_FEATURE_APRS_H_
|
#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> //
|
// Copyright (C) 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
@ -708,7 +708,7 @@ void APRSGUI::updateChannelList()
|
|||||||
ui->sourcePipes->clear();
|
ui->sourcePipes->clear();
|
||||||
|
|
||||||
for (const auto& channel : m_availableChannels) {
|
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);
|
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> //
|
// Copyright (C) 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#include "util/messagequeue.h"
|
#include "util/messagequeue.h"
|
||||||
#include "util/aprs.h"
|
#include "util/aprs.h"
|
||||||
#include "settings/rollupstate.h"
|
#include "settings/rollupstate.h"
|
||||||
|
#include "availablechannelorfeature.h"
|
||||||
|
|
||||||
#include "aprssettings.h"
|
#include "aprssettings.h"
|
||||||
|
|
||||||
@ -123,7 +124,7 @@ private:
|
|||||||
QList<QString> m_settingsKeys;
|
QList<QString> m_settingsKeys;
|
||||||
RollupState m_rollupState;
|
RollupState m_rollupState;
|
||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
QList<APRSSettings::AvailableChannel> m_availableChannels;
|
AvailableChannelOrFeatureList m_availableChannels;
|
||||||
|
|
||||||
APRS* m_aprs;
|
APRS* m_aprs;
|
||||||
MessageQueue m_inputMessageQueue;
|
MessageQueue m_inputMessageQueue;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||||
// written by Christian Daniel //
|
// written by Christian Daniel //
|
||||||
// Copyright (C) 2015-2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// 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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -38,17 +38,6 @@ class Serializable;
|
|||||||
|
|
||||||
struct APRSSettings
|
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;
|
QString m_igateServer;
|
||||||
int m_igatePort;
|
int m_igatePort;
|
||||||
QString m_igateCallsign;
|
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:
|
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-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||||
// //
|
// //
|
||||||
@ -56,6 +56,8 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface)
|
|||||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||||
m_thread(nullptr),
|
m_thread(nullptr),
|
||||||
m_worker(nullptr),
|
m_worker(nullptr),
|
||||||
|
m_availableChannelOrFeatureHandler(GS232ControllerSettings::m_pipeURIs),
|
||||||
|
m_selectedPipe(nullptr),
|
||||||
m_currentAzimuth(0.0f),
|
m_currentAzimuth(0.0f),
|
||||||
m_currentElevation(0.0f)
|
m_currentElevation(0.0f)
|
||||||
{
|
{
|
||||||
@ -63,7 +65,6 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface)
|
|||||||
setObjectName(m_featureId);
|
setObjectName(m_featureId);
|
||||||
m_state = StIdle;
|
m_state = StIdle;
|
||||||
m_errorMessage = "GS232Controller error";
|
m_errorMessage = "GS232Controller error";
|
||||||
m_selectedPipe = nullptr;
|
|
||||||
m_networkManager = new QNetworkAccessManager();
|
m_networkManager = new QNetworkAccessManager();
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
m_networkManager,
|
m_networkManager,
|
||||||
@ -71,30 +72,21 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface)
|
|||||||
this,
|
this,
|
||||||
&GS232Controller::networkManagerFinished
|
&GS232Controller::networkManagerFinished
|
||||||
);
|
);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
MainCore::instance(),
|
&m_availableChannelOrFeatureHandler,
|
||||||
&MainCore::featureAdded,
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
this,
|
this,
|
||||||
&GS232Controller::handleFeatureAdded
|
&GS232Controller::channelsOrFeaturesChanged
|
||||||
);
|
);
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
MainCore::instance(),
|
&m_availableChannelOrFeatureHandler,
|
||||||
&MainCore::channelAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&GS232Controller::handleChannelAdded
|
&GS232Controller::handlePipeMessageQueue
|
||||||
);
|
|
||||||
QObject::connect(
|
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::featureRemoved,
|
|
||||||
this,
|
|
||||||
&GS232Controller::handleFeatureRemoved
|
|
||||||
);
|
|
||||||
QObject::connect(
|
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::channelRemoved,
|
|
||||||
this,
|
|
||||||
&GS232Controller::handleChannelRemoved
|
|
||||||
);
|
);
|
||||||
|
m_availableChannelOrFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||||
|
|
||||||
connect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts);
|
connect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts);
|
||||||
m_timer.start(5000);
|
m_timer.start(5000);
|
||||||
}
|
}
|
||||||
@ -104,28 +96,16 @@ GS232Controller::~GS232Controller()
|
|||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
disconnect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts);
|
disconnect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts);
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
MainCore::instance(),
|
&m_availableChannelOrFeatureHandler,
|
||||||
&MainCore::channelRemoved,
|
&AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged,
|
||||||
this,
|
this,
|
||||||
&GS232Controller::handleChannelRemoved
|
&GS232Controller::channelsOrFeaturesChanged
|
||||||
);
|
);
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
MainCore::instance(),
|
&m_availableChannelOrFeatureHandler,
|
||||||
&MainCore::featureRemoved,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&GS232Controller::handleFeatureRemoved
|
&GS232Controller::handlePipeMessageQueue
|
||||||
);
|
|
||||||
QObject::disconnect(
|
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::channelAdded,
|
|
||||||
this,
|
|
||||||
&GS232Controller::handleChannelAdded
|
|
||||||
);
|
|
||||||
QObject::disconnect(
|
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::featureAdded,
|
|
||||||
this,
|
|
||||||
&GS232Controller::handleFeatureAdded
|
|
||||||
);
|
);
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
m_networkManager,
|
m_networkManager,
|
||||||
@ -154,8 +134,6 @@ void GS232Controller::start()
|
|||||||
GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg =
|
GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg =
|
||||||
GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(m_settings, QList<QString>(), true);
|
GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(m_settings, QList<QString>(), true);
|
||||||
m_worker->getInputMessageQueue()->push(msg);
|
m_worker->getInputMessageQueue()->push(msg);
|
||||||
|
|
||||||
scanAvailableChannelsAndFeatures();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232Controller::stop()
|
void GS232Controller::stop()
|
||||||
@ -210,7 +188,7 @@ bool GS232Controller::handleMessage(const Message& cmd)
|
|||||||
}
|
}
|
||||||
else if (MsgScanAvailableChannelOrFeatures::match(cmd))
|
else if (MsgScanAvailableChannelOrFeatures::match(cmd))
|
||||||
{
|
{
|
||||||
scanAvailableChannelsAndFeatures();
|
notifyUpdate({}, {});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (GS232ControllerReport::MsgReportAzAl::match(cmd))
|
else if (GS232ControllerReport::MsgReportAzAl::match(cmd))
|
||||||
@ -248,8 +226,6 @@ bool GS232Controller::handleMessage(const Message& cmd)
|
|||||||
applySettings(m_settings, QList<QString>{"azimuth", "elevation"});
|
applySettings(m_settings, QList<QString>{"azimuth", "elevation"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
qDebug() << "GS232Controller::handleMessage: No match " << msg.getPipeSource() << " " << m_selectedPipe;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -306,10 +282,6 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con
|
|||||||
{
|
{
|
||||||
qDebug() << "GS232Controller::applySettings:" << settings.getDebugString(settingsKeys, force) << " force: " << force;
|
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")
|
if (settingsKeys.contains("source")
|
||||||
|| (!settings.m_source.isEmpty() && (m_selectedPipe == nullptr)) // Change in available pipes
|
|| (!settings.m_source.isEmpty() && (m_selectedPipe == nullptr)) // Change in available pipes
|
||||||
|| force)
|
|| force)
|
||||||
@ -317,27 +289,24 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con
|
|||||||
MainCore *mainCore = MainCore::instance();
|
MainCore *mainCore = MainCore::instance();
|
||||||
MessagePipes& messagePipes = mainCore->getMessagePipes();
|
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");
|
messagePipes.unregisterProducerToConsumer(m_selectedPipe, this, "target");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (!settings.m_source.isEmpty())
|
m_selectedPipe = m_availableChannelOrFeatureHandler.registerPipes(settings.m_source, this, {"target"});
|
||||||
{
|
|
||||||
QObject *object = nullptr;
|
|
||||||
|
|
||||||
for (const auto& oval : m_availableChannelOrFeatures)
|
/*if (!settings.m_source.isEmpty())
|
||||||
{
|
{
|
||||||
if (settings.m_source == oval.getLongId())
|
int index = m_availableChannelOrFeatures.indexOfLongId(settings.m_source);
|
||||||
{
|
|
||||||
object = oval.m_object;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
|
QObject *object = m_availableChannelOrFeatures[index].m_object;
|
||||||
registerPipe(object);
|
registerPipe(object);
|
||||||
m_selectedPipe = object;
|
m_selectedPipe = object;
|
||||||
}
|
}
|
||||||
@ -350,7 +319,7 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_selectedPipe = nullptr;
|
m_selectedPipe = nullptr;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg = GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(
|
GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg = GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(
|
||||||
@ -718,12 +687,7 @@ void GS232Controller::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& r
|
|||||||
|
|
||||||
for (const auto& item : m_availableChannelOrFeatures)
|
for (const auto& item : m_availableChannelOrFeatures)
|
||||||
{
|
{
|
||||||
QString itemText = tr("%1%2:%3 %4")
|
QString itemText = item.getLongId();
|
||||||
.arg(item.m_kind)
|
|
||||||
.arg(item.m_superIndex)
|
|
||||||
.arg(item.m_index)
|
|
||||||
.arg(item.m_type);
|
|
||||||
|
|
||||||
response.getGs232ControllerReport()->getSources()->append(new QString(itemText));
|
response.getGs232ControllerReport()->getSources()->append(new QString(itemText));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -763,69 +727,22 @@ void GS232Controller::networkManagerFinished(QNetworkReply *reply)
|
|||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232Controller::scanAvailableChannelsAndFeatures()
|
void GS232Controller::channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo)
|
||||||
{
|
{
|
||||||
m_availableChannelOrFeatures = MainCore::instance()->getAvailableChannelsAndFeatures(GS232ControllerSettings::m_pipeURIs);
|
m_availableChannelOrFeatures = m_availableChannelOrFeatureHandler.getAvailableChannelOrFeatureList();
|
||||||
notifyUpdate();
|
notifyUpdate(renameFrom, renameTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232Controller::notifyUpdate()
|
void GS232Controller::notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo)
|
||||||
{
|
{
|
||||||
if (getMessageQueueToGUI())
|
if (getMessageQueueToGUI())
|
||||||
{
|
{
|
||||||
MsgReportAvailableChannelOrFeatures *msg = MsgReportAvailableChannelOrFeatures::create();
|
MsgReportAvailableChannelOrFeatures *msg = MsgReportAvailableChannelOrFeatures::create(renameFrom, renameTo);
|
||||||
msg->getItems() = m_availableChannelOrFeatures;
|
msg->getItems() = m_availableChannelOrFeatures;
|
||||||
getMessageQueueToGUI()->push(msg);
|
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)
|
void GS232Controller::handlePipeMessageQueue(MessageQueue* messageQueue)
|
||||||
{
|
{
|
||||||
Message* message;
|
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-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
// Copyright (C) 2020 Kacper Michajłow <kasper93@gmail.com> //
|
||||||
// //
|
// //
|
||||||
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "feature/feature.h"
|
#include "feature/feature.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
#include "maincore.h"
|
#include "maincore.h"
|
||||||
|
|
||||||
#include "gs232controllersettings.h"
|
#include "gs232controllersettings.h"
|
||||||
@ -111,17 +112,23 @@ public:
|
|||||||
MESSAGE_CLASS_DECLARATION
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
public:
|
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() {
|
static MsgReportAvailableChannelOrFeatures* create(const QStringList& renameFrom, const QStringList& renameTo) {
|
||||||
return new MsgReportAvailableChannelOrFeatures();
|
return new MsgReportAvailableChannelOrFeatures(renameFrom, renameTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<MainCore::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
AvailableChannelOrFeatureList m_availableChannelOrFeatures;
|
||||||
|
QStringList m_renameFrom;
|
||||||
|
QStringList m_renameTo;
|
||||||
|
|
||||||
MsgReportAvailableChannelOrFeatures() :
|
MsgReportAvailableChannelOrFeatures(const QStringList& renameFrom, const QStringList& renameTo) :
|
||||||
Message()
|
Message(),
|
||||||
|
m_renameFrom(renameFrom),
|
||||||
|
m_renameTo(renameTo)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -213,8 +220,8 @@ private:
|
|||||||
QThread *m_thread;
|
QThread *m_thread;
|
||||||
GS232ControllerWorker *m_worker;
|
GS232ControllerWorker *m_worker;
|
||||||
GS232ControllerSettings m_settings;
|
GS232ControllerSettings m_settings;
|
||||||
//QHash<QObject*, GS232ControllerSettings::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
AvailableChannelOrFeatureList m_availableChannelOrFeatures;
|
||||||
QList<MainCore::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
AvailableChannelOrFeatureHandler m_availableChannelOrFeatureHandler;
|
||||||
QObject *m_selectedPipe;
|
QObject *m_selectedPipe;
|
||||||
|
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
@ -231,17 +238,11 @@ private:
|
|||||||
void applySettings(const GS232ControllerSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
void applySettings(const GS232ControllerSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const GS232ControllerSettings& settings, bool force);
|
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const GS232ControllerSettings& settings, bool force);
|
||||||
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
|
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
|
||||||
void scanAvailableChannelsAndFeatures();
|
void notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void notifyUpdate();
|
|
||||||
void registerPipe(QObject *object);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void networkManagerFinished(QNetworkReply *reply);
|
void networkManagerFinished(QNetworkReply *reply);
|
||||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
void channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
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 handlePipeMessageQueue(MessageQueue* messageQueue);
|
void handlePipeMessageQueue(MessageQueue* messageQueue);
|
||||||
void scanSerialPorts();
|
void scanSerialPorts();
|
||||||
};
|
};
|
||||||
|
@ -51,7 +51,7 @@ void GS232ControllerGUI::resetToDefaults()
|
|||||||
{
|
{
|
||||||
m_settings.resetToDefaults();
|
m_settings.resetToDefaults();
|
||||||
displaySettings();
|
displaySettings();
|
||||||
applySettings(true);
|
applyAllSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray GS232ControllerGUI::serialize() const
|
QByteArray GS232ControllerGUI::serialize() const
|
||||||
@ -65,7 +65,7 @@ bool GS232ControllerGUI::deserialize(const QByteArray& data)
|
|||||||
{
|
{
|
||||||
m_feature->setWorkspaceIndex(m_settings.m_workspaceIndex);
|
m_feature->setWorkspaceIndex(m_settings.m_workspaceIndex);
|
||||||
displaySettings();
|
displaySettings();
|
||||||
applySettings(true);
|
applyAllSettings();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -121,9 +121,7 @@ void GS232ControllerGUI::displayToAzEl(float coord1, float coord2)
|
|||||||
m_settings.m_azimuth = coord1;
|
m_settings.m_azimuth = coord1;
|
||||||
m_settings.m_elevation = coord2;
|
m_settings.m_elevation = coord2;
|
||||||
}
|
}
|
||||||
m_settingsKeys.append("azimuth");
|
applySettings({"azimuth", "elevation"});
|
||||||
m_settingsKeys.append("elevation");
|
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GS232ControllerGUI::handleMessage(const Message& message)
|
bool GS232ControllerGUI::handleMessage(const Message& message)
|
||||||
@ -149,7 +147,7 @@ bool GS232ControllerGUI::handleMessage(const Message& message)
|
|||||||
{
|
{
|
||||||
GS232Controller::MsgReportAvailableChannelOrFeatures& report =
|
GS232Controller::MsgReportAvailableChannelOrFeatures& report =
|
||||||
(GS232Controller::MsgReportAvailableChannelOrFeatures&) message;
|
(GS232Controller::MsgReportAvailableChannelOrFeatures&) message;
|
||||||
updatePipeList(report.getItems());
|
updatePipeList(report.getItems(), report.getRenameFrom(), report.getRenameTo());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (GS232ControllerReport::MsgReportAzAl::match(message))
|
else if (GS232ControllerReport::MsgReportAzAl::match(message))
|
||||||
@ -206,7 +204,7 @@ void GS232ControllerGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
|||||||
(void) rollDown;
|
(void) rollDown;
|
||||||
|
|
||||||
getRollupContents()->saveState(m_rollupState);
|
getRollupContents()->saveState(m_rollupState);
|
||||||
applySettings();
|
applySetting("rollupState");
|
||||||
}
|
}
|
||||||
|
|
||||||
GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
|
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);
|
connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController);
|
||||||
|
|
||||||
displaySettings();
|
displaySettings();
|
||||||
applySettings(true);
|
applyAllSettings();
|
||||||
makeUIConnections();
|
makeUIConnections();
|
||||||
|
|
||||||
// Get pre-existing pipes
|
// Get pre-existing pipes
|
||||||
@ -408,8 +406,7 @@ void GS232ControllerGUI::on_inputController_currentIndexChanged(int index)
|
|||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
m_settings.m_inputController = ui->inputController->currentText();
|
m_settings.m_inputController = ui->inputController->currentText();
|
||||||
m_settingsKeys.append("inputController");
|
applySetting("inputController");
|
||||||
applySettings();
|
|
||||||
updateInputController();
|
updateInputController();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,28 +422,24 @@ void GS232ControllerGUI::on_highSensitivity_clicked(bool checked)
|
|||||||
{
|
{
|
||||||
m_settings.m_highSensitivity = checked;
|
m_settings.m_highSensitivity = checked;
|
||||||
ui->highSensitivity->setText(checked ? "H" : "L");
|
ui->highSensitivity->setText(checked ? "H" : "L");
|
||||||
m_settingsKeys.append("highSensitivity");
|
applySetting("highSensitivity");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_enableTargetControl_clicked(bool checked)
|
void GS232ControllerGUI::on_enableTargetControl_clicked(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_targetControlEnabled = checked;
|
m_settings.m_targetControlEnabled = checked;
|
||||||
m_settingsKeys.append("targetControlEnabled");
|
applySetting("targetControlEnabled");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_enableOffsetControl_clicked(bool checked)
|
void GS232ControllerGUI::on_enableOffsetControl_clicked(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_offsetControlEnabled = checked;
|
m_settings.m_offsetControlEnabled = checked;
|
||||||
m_settingsKeys.append("offsetControlEnabled");
|
applySetting("offsetControlEnabled");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::inputConfigurationComplete()
|
void GS232ControllerGUI::inputConfigurationComplete()
|
||||||
{
|
{
|
||||||
m_settingsKeys.append("inputControllerSettings");
|
applySetting("inputControllerSettings");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GS232ControllerGUI::~GS232ControllerGUI()
|
GS232ControllerGUI::~GS232ControllerGUI()
|
||||||
@ -546,10 +539,16 @@ void GS232ControllerGUI::updateSerialPortList(const QStringList& serialPorts)
|
|||||||
ui->serialPort->blockSignals(false);
|
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();
|
// Update source settting if it has been renamed
|
||||||
QString newText;
|
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->blockSignals(true);
|
||||||
ui->sources->clear();
|
ui->sources->clear();
|
||||||
|
|
||||||
@ -557,40 +556,33 @@ void GS232ControllerGUI::updatePipeList(const QList<MainCore::AvailableChannelOr
|
|||||||
ui->sources->addItem(source.getLongId());
|
ui->sources->addItem(source.getLongId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = ui->sources->findText(m_settings.m_source);
|
// Select current setting, if it exists
|
||||||
ui->sources->setCurrentIndex(index);
|
// 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
|
||||||
if (index < 0) // current source is not found
|
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 = "";
|
m_settings.m_source = "";
|
||||||
|
applySetting("source");
|
||||||
ui->targetName->setText("");
|
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);
|
ui->sources->blockSignals(false);
|
||||||
|
|
||||||
// QString newText = ui->sources->currentText();
|
// If no current settting, select first available
|
||||||
|
if (m_settings.m_source.isEmpty() && (ui->sources->count() > 0))
|
||||||
// if (currentText != newText)
|
{
|
||||||
// {
|
ui->sources->setCurrentIndex(0);
|
||||||
// m_settings.m_source = newText;
|
on_sources_currentTextChanged(ui->sources->currentText());
|
||||||
// ui->targetName->setText("");
|
}
|
||||||
// applySettings();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::onMenuDialogCalled(const QPoint &p)
|
void GS232ControllerGUI::onMenuDialogCalled(const QPoint &p)
|
||||||
@ -620,15 +612,17 @@ void GS232ControllerGUI::onMenuDialogCalled(const QPoint &p)
|
|||||||
setTitle(m_settings.m_title);
|
setTitle(m_settings.m_title);
|
||||||
setTitleColor(m_settings.m_rgbColor);
|
setTitleColor(m_settings.m_rgbColor);
|
||||||
|
|
||||||
m_settingsKeys.append("title");
|
QList<QString> settingsKeys({
|
||||||
m_settingsKeys.append("rgbColor");
|
"rgbColor",
|
||||||
m_settingsKeys.append("useReverseAPI");
|
"title",
|
||||||
m_settingsKeys.append("reverseAPIAddress");
|
"useReverseAPI",
|
||||||
m_settingsKeys.append("reverseAPIPort");
|
"reverseAPIAddress",
|
||||||
m_settingsKeys.append("reverseAPIFeatureSetIndex");
|
"reverseAPIPort",
|
||||||
m_settingsKeys.append("reverseAPIFeatureIndex");
|
"reverseAPIDeviceIndex",
|
||||||
|
"reverseAPIChannelIndex"
|
||||||
|
});
|
||||||
|
|
||||||
applySettings();
|
applySettings(settingsKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
resetContextMenuType();
|
resetContextMenuType();
|
||||||
@ -698,15 +692,13 @@ void GS232ControllerGUI::on_protocol_currentIndexChanged(int index)
|
|||||||
{
|
{
|
||||||
m_settings.m_protocol = (GS232ControllerSettings::Protocol)index;
|
m_settings.m_protocol = (GS232ControllerSettings::Protocol)index;
|
||||||
setProtocol(m_settings.m_protocol);
|
setProtocol(m_settings.m_protocol);
|
||||||
m_settingsKeys.append("protocol");
|
applySetting("protocol");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_connection_currentIndexChanged(int index)
|
void GS232ControllerGUI::on_connection_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
m_settings.m_connection = (GS232ControllerSettings::Connection)index;
|
m_settings.m_connection = (GS232ControllerSettings::Connection)index;
|
||||||
m_settingsKeys.append("connection");
|
applySetting("connection");
|
||||||
applySettings();
|
|
||||||
updateConnectionWidgets();
|
updateConnectionWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,30 +706,26 @@ void GS232ControllerGUI::on_serialPort_currentIndexChanged(int index)
|
|||||||
{
|
{
|
||||||
(void) index;
|
(void) index;
|
||||||
m_settings.m_serialPort = ui->serialPort->currentText();
|
m_settings.m_serialPort = ui->serialPort->currentText();
|
||||||
m_settingsKeys.append("serialPort");
|
applySetting("serialPort");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_baudRate_currentIndexChanged(int index)
|
void GS232ControllerGUI::on_baudRate_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
(void) index;
|
(void) index;
|
||||||
m_settings.m_baudRate = ui->baudRate->currentText().toInt();
|
m_settings.m_baudRate = ui->baudRate->currentText().toInt();
|
||||||
m_settingsKeys.append("baudRate");
|
applySetting("baudRate");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_host_editingFinished()
|
void GS232ControllerGUI::on_host_editingFinished()
|
||||||
{
|
{
|
||||||
m_settings.m_host = ui->host->text();
|
m_settings.m_host = ui->host->text();
|
||||||
m_settingsKeys.append("host");
|
applySetting("host");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_port_valueChanged(int value)
|
void GS232ControllerGUI::on_port_valueChanged(int value)
|
||||||
{
|
{
|
||||||
m_settings.m_port = value;
|
m_settings.m_port = value;
|
||||||
m_settingsKeys.append("port");
|
applySetting("port");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_coord1_valueChanged(double value)
|
void GS232ControllerGUI::on_coord1_valueChanged(double value)
|
||||||
@ -764,8 +752,7 @@ void GS232ControllerGUI::on_azimuthOffset_valueChanged(double value)
|
|||||||
m_inputAzOffset = value;
|
m_inputAzOffset = value;
|
||||||
}
|
}
|
||||||
m_settings.m_azimuthOffset = (float) value;
|
m_settings.m_azimuthOffset = (float) value;
|
||||||
m_settingsKeys.append("azimuthOffset");
|
applySetting("azimuthOffset");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_elevationOffset_valueChanged(double value)
|
void GS232ControllerGUI::on_elevationOffset_valueChanged(double value)
|
||||||
@ -774,58 +761,50 @@ void GS232ControllerGUI::on_elevationOffset_valueChanged(double value)
|
|||||||
m_inputElOffset = value;
|
m_inputElOffset = value;
|
||||||
}
|
}
|
||||||
m_settings.m_elevationOffset = (float) value;
|
m_settings.m_elevationOffset = (float) value;
|
||||||
m_settingsKeys.append("elevationOffset");
|
applySetting("elevationOffset");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_azimuthMin_valueChanged(int value)
|
void GS232ControllerGUI::on_azimuthMin_valueChanged(int value)
|
||||||
{
|
{
|
||||||
m_settings.m_azimuthMin = value;
|
m_settings.m_azimuthMin = value;
|
||||||
m_settingsKeys.append("azimuthMin");
|
applySetting("azimuthMin");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_azimuthMax_valueChanged(int value)
|
void GS232ControllerGUI::on_azimuthMax_valueChanged(int value)
|
||||||
{
|
{
|
||||||
m_settings.m_azimuthMax = value;
|
m_settings.m_azimuthMax = value;
|
||||||
m_settingsKeys.append("azimuthMax");
|
applySetting("azimuthMax");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_elevationMin_valueChanged(int value)
|
void GS232ControllerGUI::on_elevationMin_valueChanged(int value)
|
||||||
{
|
{
|
||||||
m_settings.m_elevationMin = value;
|
m_settings.m_elevationMin = value;
|
||||||
m_settingsKeys.append("elevationMin");
|
applySetting("elevationMin");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_elevationMax_valueChanged(int value)
|
void GS232ControllerGUI::on_elevationMax_valueChanged(int value)
|
||||||
{
|
{
|
||||||
m_settings.m_elevationMax = value;
|
m_settings.m_elevationMax = value;
|
||||||
m_settingsKeys.append("elevationMax");
|
applySetting("elevationMax");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_tolerance_valueChanged(double value)
|
void GS232ControllerGUI::on_tolerance_valueChanged(double value)
|
||||||
{
|
{
|
||||||
m_settings.m_tolerance = value;
|
m_settings.m_tolerance = value;
|
||||||
m_settingsKeys.append("tolerance");
|
applySetting("tolerance");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_precision_valueChanged(int value)
|
void GS232ControllerGUI::on_precision_valueChanged(int value)
|
||||||
{
|
{
|
||||||
m_settings.m_precision = value;
|
m_settings.m_precision = value;
|
||||||
setPrecision();
|
setPrecision();
|
||||||
m_settingsKeys.append("precision");
|
applySetting("precision");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_coordinates_currentIndexChanged(int index)
|
void GS232ControllerGUI::on_coordinates_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
m_settings.m_coordinates = (GS232ControllerSettings::Coordinates)index;
|
m_settings.m_coordinates = (GS232ControllerSettings::Coordinates)index;
|
||||||
m_settingsKeys.append("coordinates");
|
applySetting("coordinates");
|
||||||
applySettings();
|
|
||||||
|
|
||||||
float coord1, coord2;
|
float coord1, coord2;
|
||||||
azElToDisplay(m_settings.m_azimuth, m_settings.m_elevation, 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("");
|
ui->targetName->setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_settingsKeys.append("track");
|
applySetting("track");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_sources_currentTextChanged(const QString& text)
|
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));
|
qDebug("GS232ControllerGUI::on_sources_currentTextChanged: %s", qPrintable(text));
|
||||||
m_settings.m_source = text;
|
m_settings.m_source = text;
|
||||||
ui->targetName->setText("");
|
ui->targetName->setText("");
|
||||||
m_settingsKeys.append("source");
|
applySetting("source");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_dfmTrack_clicked(bool checked)
|
void GS232ControllerGUI::on_dfmTrack_clicked(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_dfmTrackOn = checked;
|
m_settings.m_dfmTrackOn = checked;
|
||||||
m_settingsKeys.append("dfmTrackOn");
|
applySetting("dfmTrackOn");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_dfmLubePumps_clicked(bool checked)
|
void GS232ControllerGUI::on_dfmLubePumps_clicked(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_dfmLubePumpsOn = checked;
|
m_settings.m_dfmLubePumpsOn = checked;
|
||||||
m_settingsKeys.append("dfmLubePumpsOn");
|
applySetting("dfmLubePumpsOn");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_dfmBrakes_clicked(bool checked)
|
void GS232ControllerGUI::on_dfmBrakes_clicked(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_dfmBrakesOn = checked;
|
m_settings.m_dfmBrakesOn = checked;
|
||||||
m_settingsKeys.append("dfmBrakesOn");
|
applySetting("dfmBrakesOn");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_dfmDrives_clicked(bool checked)
|
void GS232ControllerGUI::on_dfmDrives_clicked(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_dfmDrivesOn = checked;
|
m_settings.m_dfmDrivesOn = checked;
|
||||||
m_settingsKeys.append("dfmDrivesOn");
|
applySetting("dfmDrivesOn");
|
||||||
applySettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GS232ControllerGUI::on_dfmShowStatus_clicked()
|
void GS232ControllerGUI::on_dfmShowStatus_clicked()
|
||||||
@ -983,16 +956,27 @@ 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)
|
if (m_doApplySettings)
|
||||||
{
|
{
|
||||||
GS232Controller::MsgConfigureGS232Controller* message = GS232Controller::MsgConfigureGS232Controller::create(m_settings, m_settingsKeys, force);
|
GS232Controller::MsgConfigureGS232Controller* message = GS232Controller::MsgConfigureGS232Controller::create(m_settings, m_settingsKeys, force);
|
||||||
m_gs232Controller->getInputMessageQueue()->push(message);
|
m_gs232Controller->getInputMessageQueue()->push(message);
|
||||||
}
|
|
||||||
|
|
||||||
m_settingsKeys.clear();
|
m_settingsKeys.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GS232ControllerGUI::applyAllSettings()
|
||||||
|
{
|
||||||
|
applySettings(QStringList(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GS232ControllerGUI::makeUIConnections()
|
void GS232ControllerGUI::makeUIConnections()
|
||||||
{
|
{
|
||||||
|
@ -85,12 +85,14 @@ private:
|
|||||||
virtual ~GS232ControllerGUI();
|
virtual ~GS232ControllerGUI();
|
||||||
|
|
||||||
void blockApplySettings(bool block);
|
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 displaySettings();
|
||||||
void setProtocol(GS232ControllerSettings::Protocol protocol);
|
void setProtocol(GS232ControllerSettings::Protocol protocol);
|
||||||
void setPrecision();
|
void setPrecision();
|
||||||
void updateConnectionWidgets();
|
void updateConnectionWidgets();
|
||||||
void updatePipeList(const QList<MainCore::AvailableChannelOrFeature>& sources);
|
void updatePipeList(const AvailableChannelOrFeatureList& sources, const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
void updateSerialPortList();
|
void updateSerialPortList();
|
||||||
void updateSerialPortList(const QStringList& serialPorts);
|
void updateSerialPortList(const QStringList& serialPorts);
|
||||||
bool handleMessage(const Message& message);
|
bool handleMessage(const Message& message);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||||
// written by Christian Daniel //
|
// written by Christian Daniel //
|
||||||
// Copyright (C) 2015-2017, 2019-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// 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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -26,14 +26,6 @@
|
|||||||
#include "gs232controllersettings.h"
|
#include "gs232controllersettings.h"
|
||||||
#include "inputcontrollersettings.h"
|
#include "inputcontrollersettings.h"
|
||||||
|
|
||||||
const QStringList GS232ControllerSettings::m_pipeTypes = {
|
|
||||||
QStringLiteral("ADSBDemod"),
|
|
||||||
QStringLiteral("Map"),
|
|
||||||
QStringLiteral("SkyMap"),
|
|
||||||
QStringLiteral("StarTracker"),
|
|
||||||
QStringLiteral("SatelliteTracker")
|
|
||||||
};
|
|
||||||
|
|
||||||
const QStringList GS232ControllerSettings::m_pipeURIs = {
|
const QStringList GS232ControllerSettings::m_pipeURIs = {
|
||||||
QStringLiteral("sdrangel.channel.adsbdemod"),
|
QStringLiteral("sdrangel.channel.adsbdemod"),
|
||||||
QStringLiteral("sdrangel.feature.map"),
|
QStringLiteral("sdrangel.feature.map"),
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||||
// written by Christian Daniel //
|
// written by Christian Daniel //
|
||||||
// Copyright (C) 2015-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// 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 //
|
// 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 //
|
// 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);
|
void applySettings(const QStringList& settingsKeys, const GS232ControllerSettings& settings);
|
||||||
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
|
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
|
||||||
|
|
||||||
static const QStringList m_pipeTypes;
|
|
||||||
static const QStringList m_pipeURIs;
|
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:
|
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:
|
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:
|
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:
|
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 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 //
|
// 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 //
|
// 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";
|
const char* const Radiosonde::m_featureId = "Radiosonde";
|
||||||
|
|
||||||
Radiosonde::Radiosonde(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
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);
|
qDebug("Radiosonde::Radiosonde: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||||
setObjectName(m_featureId);
|
setObjectName(m_featureId);
|
||||||
@ -54,22 +55,22 @@ Radiosonde::Radiosonde(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
|||||||
this,
|
this,
|
||||||
&Radiosonde::networkManagerFinished
|
&Radiosonde::networkManagerFinished
|
||||||
);
|
);
|
||||||
scanAvailableChannels();
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
MainCore::instance(),
|
&m_availableChannelHandler,
|
||||||
&MainCore::channelAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&Radiosonde::handleChannelAdded
|
&Radiosonde::handleChannelMessageQueue);
|
||||||
);
|
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
Radiosonde::~Radiosonde()
|
Radiosonde::~Radiosonde()
|
||||||
{
|
{
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
MainCore::instance(),
|
&m_availableChannelHandler,
|
||||||
&MainCore::channelAdded,
|
&AvailableChannelOrFeatureHandler::messageEnqueued,
|
||||||
this,
|
this,
|
||||||
&Radiosonde::handleChannelAdded
|
&Radiosonde::handleChannelMessageQueue
|
||||||
);
|
);
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
m_networkManager,
|
m_networkManager,
|
||||||
@ -362,90 +363,6 @@ void Radiosonde::networkManagerFinished(QNetworkReply *reply)
|
|||||||
reply->deleteLater();
|
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)
|
void Radiosonde::handleChannelMessageQueue(MessageQueue* messageQueue)
|
||||||
{
|
{
|
||||||
Message* message;
|
Message* message;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "feature/feature.h"
|
#include "feature/feature.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
|
|
||||||
#include "radiosondesettings.h"
|
#include "radiosondesettings.h"
|
||||||
|
|
||||||
@ -101,7 +102,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
RadiosondeSettings m_settings;
|
RadiosondeSettings m_settings;
|
||||||
QSet<ChannelAPI*> m_availableChannels;
|
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||||
|
AvailableChannelOrFeatureList m_availableChannels;
|
||||||
|
|
||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
QNetworkRequest m_networkRequest;
|
QNetworkRequest m_networkRequest;
|
||||||
@ -110,12 +112,9 @@ private:
|
|||||||
void stop();
|
void stop();
|
||||||
void applySettings(const RadiosondeSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
void applySettings(const RadiosondeSettings& settings, const QList<QString>& settingsKeys, bool force = false);
|
||||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const RadiosondeSettings& settings, bool force);
|
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const RadiosondeSettings& settings, bool force);
|
||||||
void scanAvailableChannels();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void networkManagerFinished(QNetworkReply *reply);
|
void networkManagerFinished(QNetworkReply *reply);
|
||||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
|
||||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
|
||||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
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:
|
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:
|
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:
|
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}] } ] }}'
|
||||||
|
@ -190,6 +190,7 @@ void SkyMapGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
|||||||
(void) rollDown;
|
(void) rollDown;
|
||||||
|
|
||||||
getRollupContents()->saveState(m_rollupState);
|
getRollupContents()->saveState(m_rollupState);
|
||||||
|
applySetting("rollupState");
|
||||||
}
|
}
|
||||||
|
|
||||||
SkyMapGUI::SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
|
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_pluginAPI(pluginAPI),
|
||||||
m_featureUISet(featureUISet),
|
m_featureUISet(featureUISet),
|
||||||
m_doApplySettings(true),
|
m_doApplySettings(true),
|
||||||
m_source(nullptr)
|
m_source(nullptr),
|
||||||
|
m_availableChannelOrFeatureHandler(SkyMapSettings::m_pipeURIs, {"target", "skymap.target"})
|
||||||
{
|
{
|
||||||
m_feature = feature;
|
m_feature = feature;
|
||||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||||
@ -255,11 +257,8 @@ SkyMapGUI::SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *
|
|||||||
makeUIConnections();
|
makeUIConnections();
|
||||||
m_resizer.enableChildMouseTracking();
|
m_resizer.enableChildMouseTracking();
|
||||||
|
|
||||||
QObject::connect(MainCore::instance(), &MainCore::featureAdded, this, &SkyMapGUI::handleFeatureAdded);
|
QObject::connect(&m_availableChannelOrFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &SkyMapGUI::updateSourceList);
|
||||||
QObject::connect(MainCore::instance(), &MainCore::channelAdded, this, &SkyMapGUI::handleChannelAdded);
|
m_availableChannelOrFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||||
QObject::connect(MainCore::instance(), &MainCore::featureRemoved, this, &SkyMapGUI::handleFeatureRemoved);
|
|
||||||
QObject::connect(MainCore::instance(), &MainCore::channelRemoved, this, &SkyMapGUI::handleChannelRemoved);
|
|
||||||
updateSourceList();
|
|
||||||
|
|
||||||
connect(&m_wtml, &WTML::dataUpdated, this, &SkyMapGUI::wtmlUpdated);
|
connect(&m_wtml, &WTML::dataUpdated, this, &SkyMapGUI::wtmlUpdated);
|
||||||
m_wtml.getData();
|
m_wtml.getData();
|
||||||
@ -267,11 +266,7 @@ SkyMapGUI::SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *
|
|||||||
|
|
||||||
SkyMapGUI::~SkyMapGUI()
|
SkyMapGUI::~SkyMapGUI()
|
||||||
{
|
{
|
||||||
QObject::disconnect(MainCore::instance(), &MainCore::featureAdded, this, &SkyMapGUI::handleFeatureAdded);
|
QObject::disconnect(&m_availableChannelOrFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &SkyMapGUI::updateSourceList);
|
||||||
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);
|
|
||||||
|
|
||||||
if (m_webServer)
|
if (m_webServer)
|
||||||
{
|
{
|
||||||
m_webServer->close();
|
m_webServer->close();
|
||||||
@ -350,7 +345,6 @@ void SkyMapGUI::on_source_currentIndexChanged(int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SkyMapGUI::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
|
void SkyMapGUI::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
|
||||||
{
|
{
|
||||||
qDebug() << "SkyMapGUI::renderProcessTerminated: " << terminationStatus << "exitCode" << 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)
|
void SkyMapGUI::applySettings(const QStringList& settingsKeys, bool force)
|
||||||
{
|
{
|
||||||
|
m_settingsKeys.append(settingsKeys);
|
||||||
if (m_doApplySettings)
|
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_skymap->getInputMessageQueue()->push(message);
|
||||||
|
m_settingsKeys.clear();
|
||||||
|
|
||||||
|
m_availableChannelOrFeatureHandler.deregisterPipes(m_source, this, {"target", "skymap.target"});
|
||||||
|
|
||||||
QObject *oldSource = m_source;
|
QObject *oldSource = m_source;
|
||||||
QObject *source = MainCore::getAvailableChannelOrFeatureByLongId(m_settings.m_source, m_availableChannelOrFeatures);
|
m_source = m_availableChannelOrFeatureHandler.registerPipes(m_settings.m_source, this, {"target", "skymap.target"});
|
||||||
if (source)
|
|
||||||
{
|
|
||||||
registerPipe(source);
|
|
||||||
m_source = source;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_source = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When we change plugins, default to current date and time and My Position, until we get something different
|
// When we change plugins, default to current date and time and My Position, until we get something different
|
||||||
if (oldSource && !m_source)
|
if (oldSource && !m_source)
|
||||||
@ -497,6 +486,7 @@ void SkyMapGUI::applySettings(const QStringList& settingsKeys, bool force)
|
|||||||
MainCore::instance()->getSettings().getLongitude(),
|
MainCore::instance()->getSettings().getLongitude(),
|
||||||
MainCore::instance()->getSettings().getAltitude());
|
MainCore::instance()->getSettings().getAltitude());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,91 +774,85 @@ void SkyMapGUI::receivedEvent(const QJsonObject &obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loaded via WTML
|
static const QStringList wwtPlanets = {
|
||||||
QStringList wwtBackgrounds;
|
QStringLiteral("Sun"),
|
||||||
|
QStringLiteral("Mercury"),
|
||||||
const QStringList wwtPlanets = {
|
QStringLiteral("Venus"),
|
||||||
"Sun",
|
QStringLiteral("Earth"),
|
||||||
"Mercury",
|
QStringLiteral("Moon"),
|
||||||
"Venus",
|
QStringLiteral("Mars"),
|
||||||
"Earth",
|
QStringLiteral("Jupiter"),
|
||||||
"Moon",
|
QStringLiteral("Saturn"),
|
||||||
"Mars",
|
QStringLiteral("Uranus"),
|
||||||
"Jupiter",
|
QStringLiteral("Neptune"),
|
||||||
"Saturn",
|
QStringLiteral("Pluto"),
|
||||||
"Uranus",
|
QStringLiteral("Io"),
|
||||||
"Neptune",
|
QStringLiteral("Europa"),
|
||||||
"Pluto",
|
QStringLiteral("Ganymede"),
|
||||||
"Io",
|
QStringLiteral("Callisto")
|
||||||
"Europa",
|
|
||||||
"Ganymede",
|
|
||||||
"Callisto"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const QStringList wwtPlanetIDs = {
|
static const QStringList wwtPlanetIDs = {
|
||||||
"Sun",
|
QStringLiteral("Sun"),
|
||||||
"Mercury",
|
QStringLiteral("Mercury"),
|
||||||
"Venus",
|
QStringLiteral("Venus"),
|
||||||
"Bing Maps Aerial", //"Earth",
|
QStringLiteral("Bing Maps Aerial"), //"Earth",
|
||||||
"Moon",
|
QStringLiteral("Moon"),
|
||||||
"Visible Imagery", // Mars
|
QStringLiteral("Visible Imagery"), // Mars
|
||||||
"Jupiter",
|
QStringLiteral("Jupiter"),
|
||||||
"Saturn",
|
QStringLiteral("Saturn"),
|
||||||
"Uranus",
|
QStringLiteral("Uranus"),
|
||||||
"Neptune",
|
QStringLiteral("Neptune"),
|
||||||
"Pluto (New Horizons)",
|
QStringLiteral("Pluto (New Horizons)"),
|
||||||
"Io",
|
QStringLiteral("Io"),
|
||||||
"Europa",
|
QStringLiteral("Europa"),
|
||||||
"Ganymede",
|
QStringLiteral("Ganymede"),
|
||||||
"Callisto"
|
QStringLiteral("Callisto")
|
||||||
};
|
};
|
||||||
|
|
||||||
// From https://github.com/cds-astro/aladin-lite/blob/master/src/js/ImageLayer.js
|
// From https://github.com/cds-astro/aladin-lite/blob/master/src/js/ImageLayer.js
|
||||||
const QStringList aladinBackgrounds = {
|
static const QStringList aladinBackgrounds = {
|
||||||
"DSS colored",
|
QStringLiteral("DSS colored"),
|
||||||
"DSS2 Red (F+R)",
|
QStringLiteral("DSS2 Red (F+R)"),
|
||||||
"2MASS colored",
|
QStringLiteral("2MASS colored"),
|
||||||
"Density map for Gaia EDR3 (I/350/gaiaedr3)",
|
QStringLiteral("Density map for Gaia EDR3 (I/350/gaiaedr3)"),
|
||||||
"PanSTARRS DR1 g",
|
QStringLiteral("PanSTARRS DR1 g"),
|
||||||
"PanSTARRS DR1 color",
|
QStringLiteral("PanSTARRS DR1 color"),
|
||||||
"DECaPS DR1 color",
|
QStringLiteral("DECaPS DR1 color"),
|
||||||
"Fermi color",
|
QStringLiteral("Fermi color"),
|
||||||
"Halpha",
|
QStringLiteral("Halpha"),
|
||||||
"GALEXGR6_7 NUV",
|
QStringLiteral("GALEXGR6_7 NUV"),
|
||||||
"IRIS colored",
|
QStringLiteral("IRIS colored"),
|
||||||
"Mellinger colored",
|
QStringLiteral("Mellinger colored"),
|
||||||
"SDSS9 colored",
|
QStringLiteral("SDSS9 colored"),
|
||||||
"SDSS9 band-g",
|
QStringLiteral("SDSS9 band-g"),
|
||||||
"IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)",
|
QStringLiteral("IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)"),
|
||||||
"VTSS-Ha",
|
QStringLiteral("VTSS-Ha"),
|
||||||
"XMM PN colored",
|
QStringLiteral("XMM PN colored"),
|
||||||
"AllWISE color",
|
QStringLiteral("AllWISE color"),
|
||||||
"GLIMPSE360"
|
QStringLiteral("GLIMPSE360")
|
||||||
};
|
};
|
||||||
|
|
||||||
const QStringList aladinBackgroundIDs = {
|
static const QStringList aladinBackgroundIDs = {
|
||||||
"P/DSS2/color",
|
QStringLiteral("P/DSS2/color"),
|
||||||
"P/DSS2/red",
|
QStringLiteral("P/DSS2/red"),
|
||||||
"P/2MASS/color",
|
QStringLiteral("P/2MASS/color"),
|
||||||
"P/DM/I/350/gaiaedr3",
|
QStringLiteral("P/DM/I/350/gaiaedr3"),
|
||||||
"P/PanSTARRS/DR1/g",
|
QStringLiteral("P/PanSTARRS/DR1/g"),
|
||||||
"P/PanSTARRS/DR1/color-z-zg-g",
|
QStringLiteral("P/PanSTARRS/DR1/color-z-zg-g"),
|
||||||
"P/DECaPS/DR1/color",
|
QStringLiteral("P/DECaPS/DR1/color"),
|
||||||
"P/Fermi/color",
|
QStringLiteral("P/Fermi/color"),
|
||||||
"P/Finkbeiner",
|
QStringLiteral("P/Finkbeiner"),
|
||||||
"P/GALEXGR6_7/NUV",
|
QStringLiteral("P/GALEXGR6_7/NUV"),
|
||||||
"P/IRIS/color",
|
QStringLiteral("P/IRIS/color"),
|
||||||
"P/Mellinger/color",
|
QStringLiteral("P/Mellinger/color"),
|
||||||
"P/SDSS9/color",
|
QStringLiteral("P/SDSS9/color"),
|
||||||
"P/SDSS9/g",
|
QStringLiteral("P/SDSS9/g"),
|
||||||
"P/SPITZER/color",
|
QStringLiteral("P/SPITZER/color"),
|
||||||
"P/VTSS/Ha",
|
QStringLiteral("P/VTSS/Ha"),
|
||||||
"xcatdb/P/XMM/PN/color",
|
QStringLiteral("xcatdb/P/XMM/PN/color"),
|
||||||
"P/allWISE/color",
|
QStringLiteral("P/allWISE/color"),
|
||||||
"P/GLIMPSE360"
|
QStringLiteral("P/GLIMPSE360")
|
||||||
};
|
|
||||||
|
|
||||||
const QStringList esaSkyBackgrounds = {
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QString SkyMapGUI::backgroundID(const QString& name)
|
QString SkyMapGUI::backgroundID(const QString& name)
|
||||||
@ -906,7 +890,7 @@ void SkyMapGUI::updateBackgrounds()
|
|||||||
|
|
||||||
if (m_settings.m_map == "WWT") {
|
if (m_settings.m_map == "WWT") {
|
||||||
if (m_settings.m_projection == "Sky") {
|
if (m_settings.m_projection == "Sky") {
|
||||||
backgrounds = wwtBackgrounds;
|
backgrounds = m_wwtBackgrounds;
|
||||||
} else if (m_settings.m_projection == "Solar system") {
|
} else if (m_settings.m_projection == "Solar system") {
|
||||||
backgrounds = wwtPlanets;
|
backgrounds = wwtPlanets;
|
||||||
} else {
|
} else {
|
||||||
@ -936,11 +920,11 @@ void SkyMapGUI::updateBackgrounds()
|
|||||||
|
|
||||||
void SkyMapGUI::wtmlUpdated(const QList<WTML::ImageSet>& dataSets)
|
void SkyMapGUI::wtmlUpdated(const QList<WTML::ImageSet>& dataSets)
|
||||||
{
|
{
|
||||||
wwtBackgrounds.clear();
|
m_wwtBackgrounds.clear();
|
||||||
for (int i = 0; i < dataSets.size(); i++)
|
for (int i = 0; i < dataSets.size(); i++)
|
||||||
{
|
{
|
||||||
if (dataSets[i].m_dataSetType == "Sky") {
|
if (dataSets[i].m_dataSetType == "Sky") {
|
||||||
wwtBackgrounds.append(dataSets[i].m_name);
|
m_wwtBackgrounds.append(dataSets[i].m_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateBackgrounds();
|
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->blockSignals(true);
|
||||||
ui->source->clear();
|
ui->source->clear();
|
||||||
|
|
||||||
@ -1038,89 +1030,37 @@ void SkyMapGUI::updateSourceList()
|
|||||||
ui->source->addItem(item.getLongId());
|
ui->source->addItem(item.getLongId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select current setting, if exists
|
// Select current setting, if it exists
|
||||||
// If not, make sure nothing selected, as channel may be created later on
|
// 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);
|
int idx = ui->source->findText(m_settings.m_source);
|
||||||
if (idx >= 0)
|
if (idx >= 0)
|
||||||
{
|
{
|
||||||
ui->source->setCurrentIndex(idx);
|
ui->source->setCurrentIndex(idx);
|
||||||
ui->track->setEnabled(true);
|
ui->track->setEnabled(true);
|
||||||
}
|
}
|
||||||
else
|
else if (prevIdx == -1)
|
||||||
{
|
{
|
||||||
ui->source->setCurrentIndex(-1);
|
ui->source->setCurrentIndex(-1);
|
||||||
ui->track->setChecked(false);
|
ui->track->setChecked(false);
|
||||||
ui->track->setEnabled(false);
|
ui->track->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_settings.m_source = "";
|
||||||
|
applySetting("source");
|
||||||
|
}
|
||||||
|
|
||||||
ui->source->blockSignals(false);
|
ui->source->blockSignals(false);
|
||||||
|
|
||||||
// If no current settting, select first available
|
// 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);
|
ui->source->setCurrentIndex(0);
|
||||||
on_source_currentIndexChanged(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)
|
void SkyMapGUI::handlePipeMessageQueue(MessageQueue* messageQueue)
|
||||||
{
|
{
|
||||||
Message* message;
|
Message* message;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "feature/featuregui.h"
|
#include "feature/featuregui.h"
|
||||||
#include "util/messagequeue.h"
|
#include "util/messagequeue.h"
|
||||||
#include "settings/rollupstate.h"
|
#include "settings/rollupstate.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
#include "maincore.h"
|
#include "maincore.h"
|
||||||
|
|
||||||
#include "skymapsettings.h"
|
#include "skymapsettings.h"
|
||||||
@ -72,10 +73,12 @@ private:
|
|||||||
PluginAPI* m_pluginAPI;
|
PluginAPI* m_pluginAPI;
|
||||||
FeatureUISet* m_featureUISet;
|
FeatureUISet* m_featureUISet;
|
||||||
SkyMapSettings m_settings;
|
SkyMapSettings m_settings;
|
||||||
|
QList<QString> m_settingsKeys;
|
||||||
RollupState m_rollupState;
|
RollupState m_rollupState;
|
||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
QList<MainCore::AvailableChannelOrFeature> m_availableChannelOrFeatures;
|
|
||||||
QObject *m_source;
|
QObject *m_source;
|
||||||
|
AvailableChannelOrFeatureList m_availableChannelOrFeatures;
|
||||||
|
AvailableChannelOrFeatureHandler m_availableChannelOrFeatureHandler;
|
||||||
|
|
||||||
SkyMap* m_skymap;
|
SkyMap* m_skymap;
|
||||||
MessageQueue m_inputMessageQueue;
|
MessageQueue m_inputMessageQueue;
|
||||||
@ -90,6 +93,8 @@ private:
|
|||||||
double m_dec;
|
double m_dec;
|
||||||
QDateTime m_dateTime; //!< Date time from source plugin
|
QDateTime m_dateTime; //!< Date time from source plugin
|
||||||
|
|
||||||
|
QStringList m_wwtBackgrounds;
|
||||||
|
|
||||||
explicit SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
|
explicit SkyMapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
|
||||||
virtual ~SkyMapGUI();
|
virtual ~SkyMapGUI();
|
||||||
|
|
||||||
@ -112,8 +117,6 @@ private:
|
|||||||
void updateProjection();
|
void updateProjection();
|
||||||
void find(const QString& text);
|
void find(const QString& text);
|
||||||
void sendToRotator(const QString& name, double az, double alt);
|
void sendToRotator(const QString& name, double az, double alt);
|
||||||
void updateSourceList();
|
|
||||||
void registerPipe(QObject *object);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onMenuDialogCalled(const QPoint &p);
|
void onMenuDialogCalled(const QPoint &p);
|
||||||
@ -140,11 +143,7 @@ private slots:
|
|||||||
void preferenceChanged(int elementType);
|
void preferenceChanged(int elementType);
|
||||||
void receivedEvent(const QJsonObject &obj);
|
void receivedEvent(const QJsonObject &obj);
|
||||||
void wtmlUpdated(const QList<WTML::ImageSet>& dataSets);
|
void wtmlUpdated(const QList<WTML::ImageSet>& dataSets);
|
||||||
|
void updateSourceList(const QStringList& renameFrom, const QStringList& renameTo);
|
||||||
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 handlePipeMessageQueue(MessageQueue* messageQueue);
|
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> //
|
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// 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::MsgConfigureStarTracker, Message)
|
||||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgStartStop, Message)
|
MESSAGE_CLASS_DEFINITION(StarTracker::MsgStartStop, Message)
|
||||||
MESSAGE_CLASS_DEFINITION(StarTracker::MsgSetSolarFlux, 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_featureIdURI = "sdrangel.feature.startracker";
|
||||||
const char* const StarTracker::m_featureId = "StarTracker";
|
const char* const StarTracker::m_featureId = "StarTracker";
|
||||||
@ -50,7 +51,9 @@ const char* const StarTracker::m_featureId = "StarTracker";
|
|||||||
StarTracker::StarTracker(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
StarTracker::StarTracker(WebAPIAdapterInterface *webAPIAdapterInterface) :
|
||||||
Feature(m_featureIdURI, webAPIAdapterInterface),
|
Feature(m_featureIdURI, webAPIAdapterInterface),
|
||||||
m_thread(nullptr),
|
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);
|
qDebug("StarTracker::StarTracker: webAPIAdapterInterface: %p", webAPIAdapterInterface);
|
||||||
setObjectName(m_featureId);
|
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/408mhz_ra_dec.fits"));
|
||||||
m_temps.append(new FITS(":/startracker/startracker/1420mhz_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");
|
m_spectralIndex = new FITS(":/startracker/startracker/408mhz_ra_dec_spectral_index.fits");
|
||||||
scanAvailableChannels();
|
|
||||||
scanAvailableFeatures();
|
QObject::connect(&m_availableChannelHandler, &AvailableChannelOrFeatureHandler::messageEnqueued, this, &StarTracker::handleChannelMessageQueue);
|
||||||
QObject::connect(
|
m_availableChannelHandler.scanAvailableChannelsAndFeatures();
|
||||||
MainCore::instance(),
|
QObject::connect(&m_availableFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &StarTracker::featuresChanged);
|
||||||
&MainCore::channelAdded,
|
m_availableFeatureHandler.scanAvailableChannelsAndFeatures();
|
||||||
this,
|
|
||||||
&StarTracker::handleChannelAdded
|
|
||||||
);
|
|
||||||
QObject::connect(
|
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::featureAdded,
|
|
||||||
this,
|
|
||||||
&StarTracker::handleFeatureAdded
|
|
||||||
);
|
|
||||||
QObject::connect(
|
|
||||||
MainCore::instance(),
|
|
||||||
&MainCore::featureRemoved,
|
|
||||||
this,
|
|
||||||
&StarTracker::handleFeatureRemoved
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StarTracker::~StarTracker()
|
StarTracker::~StarTracker()
|
||||||
{
|
{
|
||||||
QObject::disconnect(
|
QObject::disconnect(&m_availableChannelHandler, &AvailableChannelOrFeatureHandler::messageEnqueued, this, &StarTracker::handleChannelMessageQueue);
|
||||||
MainCore::instance(),
|
QObject::disconnect(&m_availableFeatureHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &StarTracker::featuresChanged);
|
||||||
&MainCore::channelAdded,
|
|
||||||
this,
|
|
||||||
&StarTracker::handleChannelAdded
|
|
||||||
);
|
|
||||||
QObject::disconnect(
|
QObject::disconnect(
|
||||||
m_networkManager,
|
m_networkManager,
|
||||||
&QNetworkAccessManager::finished,
|
&QNetworkAccessManager::finished,
|
||||||
@ -176,6 +160,11 @@ bool StarTracker::handleMessage(const Message& cmd)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (MsgRequestAvailableFeatures::match(cmd))
|
||||||
|
{
|
||||||
|
notifyUpdateFeatures();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (MsgSetSolarFlux::match(cmd))
|
else if (MsgSetSolarFlux::match(cmd))
|
||||||
{
|
{
|
||||||
MsgSetSolarFlux& msg = (MsgSetSolarFlux&) 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();
|
m_availableFeatures = m_availableFeatureHandler.getAvailableChannelOrFeatureList();
|
||||||
MessagePipes& messagePipes = mainCore->getMessagePipes();
|
notifyUpdateFeatures();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StarTracker::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel)
|
void StarTracker::notifyUpdateFeatures()
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
if (getMessageQueueToGUI())
|
if (getMessageQueueToGUI())
|
||||||
{
|
{
|
||||||
MsgReportAvailableSatelliteTrackers *msg = MsgReportAvailableSatelliteTrackers::create();
|
MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create();
|
||||||
msg->getFeatures() = m_satelliteTrackers.values();
|
msg->getFeatures() = m_availableFeatures;
|
||||||
getMessageQueueToGUI()->push(msg);
|
getMessageQueueToGUI()->push(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2020-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// Copyright (C) 2020-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// Copyright (C) 2020 Kacper Michajłow <kasper93@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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QSet>
|
|
||||||
|
|
||||||
#include "feature/feature.h"
|
#include "feature/feature.h"
|
||||||
#include "util/message.h"
|
#include "util/message.h"
|
||||||
#include "util/fits.h"
|
#include "util/fits.h"
|
||||||
|
#include "availablechannelorfeaturehandler.h"
|
||||||
|
|
||||||
#include "startrackersettings.h"
|
#include "startrackersettings.h"
|
||||||
|
|
||||||
@ -107,20 +107,34 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
class MsgReportAvailableSatelliteTrackers : public Message {
|
class MsgRequestAvailableFeatures : public Message {
|
||||||
MESSAGE_CLASS_DECLARATION
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QList<StarTrackerSettings::AvailableFeature>& getFeatures() { return m_availableFeatures; }
|
static MsgRequestAvailableFeatures* create() {
|
||||||
|
return new MsgRequestAvailableFeatures();
|
||||||
static MsgReportAvailableSatelliteTrackers* create() {
|
|
||||||
return new MsgReportAvailableSatelliteTrackers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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()
|
Message()
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@ -183,11 +197,13 @@ private:
|
|||||||
|
|
||||||
QNetworkAccessManager *m_networkManager;
|
QNetworkAccessManager *m_networkManager;
|
||||||
QNetworkRequest m_networkRequest;
|
QNetworkRequest m_networkRequest;
|
||||||
QSet<ChannelAPI*> m_availableChannels;
|
|
||||||
QHash<Feature*, StarTrackerSettings::AvailableFeature> m_satelliteTrackers;
|
|
||||||
Weather *m_weather;
|
Weather *m_weather;
|
||||||
float m_solarFlux;
|
float m_solarFlux;
|
||||||
|
|
||||||
|
AvailableChannelOrFeatureHandler m_availableChannelHandler;
|
||||||
|
AvailableChannelOrFeatureHandler m_availableFeatureHandler;
|
||||||
|
AvailableChannelOrFeatureList m_availableFeatures;
|
||||||
|
|
||||||
QList<FITS*> m_temps;
|
QList<FITS*> m_temps;
|
||||||
FITS *m_spectralIndex;
|
FITS *m_spectralIndex;
|
||||||
|
|
||||||
@ -197,17 +213,12 @@ private:
|
|||||||
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const StarTrackerSettings& settings, bool force);
|
void webapiReverseSendSettings(const QList<QString>& featureSettingsKeys, const StarTrackerSettings& settings, bool force);
|
||||||
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
|
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
|
||||||
double applyBeam(const FITS *fits, double beamwidth, double ra, double dec, int& imgX, int& imgY) const;
|
double applyBeam(const FITS *fits, double beamwidth, double ra, double dec, int& imgX, int& imgY) const;
|
||||||
void scanAvailableChannels();
|
void notifyUpdateFeatures();
|
||||||
void scanAvailableFeatures();
|
|
||||||
void notifyUpdateSatelliteTrackers();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void networkManagerFinished(QNetworkReply *reply);
|
void networkManagerFinished(QNetworkReply *reply);
|
||||||
void weatherUpdated(float temperature, float pressure, float humidity);
|
void weatherUpdated(float temperature, float pressure, float humidity);
|
||||||
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
|
void featuresChanged();
|
||||||
void handleMessagePipeToBeDeleted(int reason, QObject* object);
|
|
||||||
void handleFeatureAdded(int featureSetIndex, Feature *feature);
|
|
||||||
void handleFeatureRemoved(int featureSetIndex, Feature *feature);
|
|
||||||
void handleChannelMessageQueue(MessageQueue* messageQueue);
|
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> //
|
// Copyright (C) 2021-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
@ -220,17 +220,17 @@ bool StarTrackerGUI::handleMessage(const Message& message)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (StarTracker::MsgReportAvailableSatelliteTrackers::match(message))
|
else if (StarTracker::MsgReportAvailableFeatures::match(message))
|
||||||
{
|
{
|
||||||
StarTracker::MsgReportAvailableSatelliteTrackers& report = (StarTracker::MsgReportAvailableSatelliteTrackers&) message;
|
StarTracker::MsgReportAvailableFeatures& report = (StarTracker::MsgReportAvailableFeatures&) message;
|
||||||
updateSatelliteTrackerList(report.getFeatures());
|
updateFeatureList(report.getFeatures());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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
|
// Update list of plugins we can get target from
|
||||||
ui->target->blockSignals(true);
|
ui->target->blockSignals(true);
|
||||||
@ -242,9 +242,9 @@ void StarTrackerGUI::updateSatelliteTrackerList(const QList<StarTrackerSettings:
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
if (text.contains("SatelliteTracker") || text.contains("SkyMap"))
|
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;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -263,9 +263,9 @@ void StarTrackerGUI::updateSatelliteTrackerList(const QList<StarTrackerSettings:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add new targets
|
// 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) {
|
if (ui->target->findText(name) == -1) {
|
||||||
ui->target->addItem(name);
|
ui->target->addItem(name);
|
||||||
}
|
}
|
||||||
@ -454,6 +454,9 @@ StarTrackerGUI::StarTrackerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet,
|
|||||||
|
|
||||||
createGalacticLineOfSightScene();
|
createGalacticLineOfSightScene();
|
||||||
plotChart();
|
plotChart();
|
||||||
|
|
||||||
|
StarTracker::MsgRequestAvailableFeatures *message = StarTracker::MsgRequestAvailableFeatures::create();
|
||||||
|
m_starTracker->getInputMessageQueue()->push(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
StarTrackerGUI::~StarTrackerGUI()
|
StarTrackerGUI::~StarTrackerGUI()
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "util/fits.h"
|
#include "util/fits.h"
|
||||||
#include "gui/httpdownloadmanagergui.h"
|
#include "gui/httpdownloadmanagergui.h"
|
||||||
#include "settings/rollupstate.h"
|
#include "settings/rollupstate.h"
|
||||||
|
#include "availablechannelorfeature.h"
|
||||||
|
|
||||||
#include "startrackersettings.h"
|
#include "startrackersettings.h"
|
||||||
|
|
||||||
@ -169,7 +170,7 @@ private:
|
|||||||
void updateSolarFlux(bool all);
|
void updateSolarFlux(bool all);
|
||||||
void makeUIConnections();
|
void makeUIConnections();
|
||||||
void limitAzElRange(double& azimuth, double& elevation) const;
|
void limitAzElRange(double& azimuth, double& elevation) const;
|
||||||
void updateSatelliteTrackerList(const QList<StarTrackerSettings::AvailableFeature>& satelliteTrackers);
|
void updateFeatureList(const AvailableChannelOrFeatureList& features);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onMenuDialogCalled(const QPoint &p);
|
void onMenuDialogCalled(const QPoint &p);
|
||||||
|
@ -23,14 +23,6 @@
|
|||||||
|
|
||||||
#include "startrackersettings.h"
|
#include "startrackersettings.h"
|
||||||
|
|
||||||
const QStringList StarTrackerSettings::m_pipeTypes = {
|
|
||||||
QStringLiteral("RadioAstronomy")
|
|
||||||
};
|
|
||||||
|
|
||||||
const QStringList StarTrackerSettings::m_pipeURIs = {
|
|
||||||
QStringLiteral("sdrangel.channel.radioastronomy")
|
|
||||||
};
|
|
||||||
|
|
||||||
StarTrackerSettings::StarTrackerSettings() :
|
StarTrackerSettings::StarTrackerSettings() :
|
||||||
m_rollupState(nullptr)
|
m_rollupState(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||||
// written by Christian Daniel //
|
// written by Christian Daniel //
|
||||||
// Copyright (C) 2015-2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
// 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 //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -30,23 +30,6 @@ class Serializable;
|
|||||||
|
|
||||||
struct StarTrackerSettings
|
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_ra;
|
||||||
QString m_dec;
|
QString m_dec;
|
||||||
double m_latitude;
|
double m_latitude;
|
||||||
@ -102,9 +85,6 @@ struct StarTrackerSettings
|
|||||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||||
void applySettings(const QStringList& settingsKeys, const StarTrackerSettings& settings);
|
void applySettings(const QStringList& settingsKeys, const StarTrackerSettings& settings);
|
||||||
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
|
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
|
||||||
|
|
||||||
static const QStringList m_pipeTypes;
|
|
||||||
static const QStringList m_pipeURIs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDE_FEATURE_STARTRACKERSETTINGS_H_
|
#endif // INCLUDE_FEATURE_STARTRACKERSETTINGS_H_
|
||||||
|
@ -286,6 +286,8 @@ set(sdrbase_SOURCES
|
|||||||
|
|
||||||
websockets/wsspectrum.cpp
|
websockets/wsspectrum.cpp
|
||||||
|
|
||||||
|
availablechannelorfeature.cpp
|
||||||
|
availablechannelorfeaturehandler.cpp
|
||||||
mainparser.cpp
|
mainparser.cpp
|
||||||
maincore.cpp
|
maincore.cpp
|
||||||
remotetcpsinkstarter.cpp
|
remotetcpsinkstarter.cpp
|
||||||
@ -525,6 +527,8 @@ set(sdrbase_HEADERS
|
|||||||
|
|
||||||
websockets/wsspectrum.h
|
websockets/wsspectrum.h
|
||||||
|
|
||||||
|
availablechannelorfeature.h
|
||||||
|
availablechannelorfeaturehandler.h
|
||||||
mainparser.h
|
mainparser.h
|
||||||
maincore.h
|
maincore.h
|
||||||
remotetcpsinkstarter.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
|
#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)
|
for (const auto deviceSet : m_deviceSets)
|
||||||
{
|
{
|
||||||
@ -467,9 +467,9 @@ QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableChannels(const
|
|||||||
return list;
|
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();
|
std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
|
||||||
|
|
||||||
for (const auto& featureSet : featureSets)
|
for (const auto& featureSet : featureSets)
|
||||||
@ -496,37 +496,18 @@ QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableFeatures(const
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<MainCore::AvailableChannelOrFeature> MainCore::getAvailableChannelsAndFeatures(const QStringList& uris)
|
AvailableChannelOrFeatureList MainCore::getAvailableChannelsAndFeatures(const QStringList& uris, const QString& kinds)
|
||||||
{
|
{
|
||||||
QList<AvailableChannelOrFeature> list;
|
AvailableChannelOrFeatureList list;
|
||||||
|
|
||||||
|
if (kinds != "F") {
|
||||||
list.append(getAvailableChannels(uris));
|
list.append(getAvailableChannels(uris));
|
||||||
|
}
|
||||||
|
if (kinds.contains("F")) {
|
||||||
list.append(getAvailableFeatures(uris));
|
list.append(getAvailableFeatures(uris));
|
||||||
|
}
|
||||||
|
|
||||||
return list;
|
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)
|
QChar MainCore::getDeviceSetTypeId(const DeviceSet* deviceSet)
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "pipes/messagepipes.h"
|
#include "pipes/messagepipes.h"
|
||||||
#include "pipes/datapipes.h"
|
#include "pipes/datapipes.h"
|
||||||
#include "channel/channelapi.h"
|
#include "channel/channelapi.h"
|
||||||
|
#include "availablechannelorfeature.h"
|
||||||
|
|
||||||
class DeviceSet;
|
class DeviceSet;
|
||||||
class FeatureSet;
|
class FeatureSet;
|
||||||
@ -908,39 +909,10 @@ public:
|
|||||||
// Position
|
// Position
|
||||||
const QGeoPositionInfo& getPosition() const;
|
const QGeoPositionInfo& getPosition() const;
|
||||||
|
|
||||||
struct AvailableChannelOrFeature
|
// 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.
|
||||||
QChar m_kind; //!< 'R' or 'T' for channel, 'M' for MIMO channel, 'F' for feature as from MainCore::getDeviceSetTypeId
|
AvailableChannelOrFeatureList getAvailableFeatures(const QStringList& uris); // Get list of available features with given URIs or all if empty list.
|
||||||
int m_superIndex; //!< Device Set index or Feature Set index
|
AvailableChannelOrFeatureList getAvailableChannelsAndFeatures(const QStringList& uris, const QString& kinds); // Get list of available channels and features with given URIs or all if empty list.
|
||||||
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);
|
|
||||||
|
|
||||||
// Ids
|
// Ids
|
||||||
QChar getDeviceSetTypeId(const DeviceSet* deviceSet); //!< Get Type Id (E.g. 'R', 'T' or 'M') for the given device set
|
QChar getDeviceSetTypeId(const DeviceSet* deviceSet); //!< Get Type Id (E.g. 'R', 'T' or 'M') for the given device set
|
||||||
|
Loading…
x
Reference in New Issue
Block a user