diff --git a/plugins/channelrx/freqscanner/freqscanner.cpp b/plugins/channelrx/freqscanner/freqscanner.cpp index 653f2cc4a..6d4c3c509 100644 --- a/plugins/channelrx/freqscanner/freqscanner.cpp +++ b/plugins/channelrx/freqscanner/freqscanner.cpp @@ -67,6 +67,7 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) : m_basebandSink(nullptr), m_running(false), m_basebandSampleRate(0), + m_availableChannelHandler({}), m_scanDeviceSetIndex(0), m_scanChannelIndex(0), m_state(IDLE), @@ -95,19 +96,8 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) : start(); - scanAvailableChannels(); - QObject::connect( - MainCore::instance(), - &MainCore::channelAdded, - this, - &FreqScanner::handleChannelAdded - ); - QObject::connect( - MainCore::instance(), - &MainCore::channelRemoved, - this, - &FreqScanner::handleChannelRemoved - ); + QObject::connect(&m_availableChannelHandler, &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, &FreqScanner::channelsChanged); + m_availableChannelHandler.scanAvailableChannelsAndFeatures(); m_timeoutTimer.callOnTimeout(this, &FreqScanner::timeout); } @@ -708,7 +698,7 @@ void FreqScanner::applySettings(const FreqScannerSettings& settings, const QStri m_deviceAPI->removeChannelSink(this, m_settings.m_streamIndex); m_deviceAPI->addChannelSink(this, settings.m_streamIndex); m_deviceAPI->addChannelSinkAPI(this); - scanAvailableChannels(); // re-scan + //FIXME:scanAvailableChannels(); // re-scan emit streamIndexChanged(settings.m_streamIndex); } } @@ -1116,186 +1106,18 @@ void FreqScanner::handleIndexInDeviceSetChanged(int index) m_basebandSink->setFifoLabel(fifoLabel); } -void FreqScanner::scanAvailableChannels() +void FreqScanner::channelsChanged(const QStringList& renameFrom, const QStringList& renameTo) { - m_availableChannels.clear(); - - DSPDeviceSourceEngine* deviceSourceEngine = getDeviceAPI()->getDeviceSourceEngine(); - - if (deviceSourceEngine) - { - for (int chi = 0; chi < getDeviceAPI()->getNbSinkChannels(); chi++) // Rx channels - { - ChannelAPI* channel = getDeviceAPI()->getChanelSinkAPIAt(chi); - - if (channel->getIndexInDeviceSet() == getIndexInDeviceSet()) { // Exclude oneself - continue; - } - - FreqScannerSettings::AvailableChannel availableChannel = - FreqScannerSettings::AvailableChannel{ - channel->getDeviceSetIndex(), - channel->getIndexInDeviceSet(), - -1 - }; - m_availableChannels[channel] = availableChannel; - QObject::connect( - channel, - &ChannelAPI::streamIndexChanged, - [=](int streamIndex){ - this->handleChannelStreamIndexChanged(streamIndex, channel); - } - ); - } - } - - DSPDeviceMIMOEngine *deviceMIMOEngine = getDeviceAPI()->getDeviceMIMOEngine(); - - if (deviceMIMOEngine) - { - for (int chi = 0; chi < getDeviceAPI()->getNbSinkChannels(); chi++) // Rx channels - { - ChannelAPI* channel = getDeviceAPI()->getChanelSinkAPIAt(chi); - - if (channel->getIndexInDeviceSet() == getIndexInDeviceSet()) { // Exclude oneself - continue; - } - - // Single Rx on the same I/Q stream - if ((channel->getNbSinkStreams() == 1) - && (channel->getNbSourceStreams() == 0) - && (channel->getStreamIndex() == m_settings.m_streamIndex)) - { - FreqScannerSettings::AvailableChannel availableChannel = - FreqScannerSettings::AvailableChannel{ - channel->getDeviceSetIndex(), - channel->getIndexInDeviceSet(), - channel->getStreamIndex() - }; - m_availableChannels[channel] = availableChannel; - QObject::connect( - channel, - &ChannelAPI::streamIndexChanged, - [=](int streamIndex){ - this->handleChannelStreamIndexChanged(streamIndex, channel); - } - ); - } - } - } - - notifyUpdateChannels(); + m_availableChannels = m_availableChannelHandler.getAvailableChannelOrFeatureList(); + notifyUpdateChannels(renameFrom, renameTo); } -void FreqScanner::handleChannelAdded(int deviceSetIndex, ChannelAPI* channel) -{ - if (deviceSetIndex != getDeviceSetIndex()) { // Can control channels only in the same device set - return; - } - - qDebug("FreqScanner::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)", - deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel); - DSPDeviceSourceEngine* deviceSourceEngine = getDeviceAPI()->getDeviceSourceEngine(); - - if (deviceSourceEngine) - { - FreqScannerSettings::AvailableChannel availableChannel = - FreqScannerSettings::AvailableChannel{ deviceSetIndex, channel->getIndexInDeviceSet(), -1}; - m_availableChannels[channel] = availableChannel; - QObject::connect( - channel, - &ChannelAPI::streamIndexChanged, - [=](int streamIndex){ - this->handleChannelStreamIndexChanged(streamIndex, channel); - } - ); - } - - DSPDeviceMIMOEngine *deviceMIMOEngine = getDeviceAPI()->getDeviceMIMOEngine(); - - if (deviceMIMOEngine - && (channel->getNbSinkStreams() == 1) - && (channel->getNbSourceStreams() == 0) - && (channel->getStreamIndex() == m_settings.m_streamIndex)) - { - FreqScannerSettings::AvailableChannel availableChannel = - FreqScannerSettings::AvailableChannel{ - deviceSetIndex, - channel->getIndexInDeviceSet(), - channel->getStreamIndex() - }; - m_availableChannels[channel] = availableChannel; - QObject::connect( - channel, - &ChannelAPI::streamIndexChanged, - [=](int streamIndex){ - this->handleChannelStreamIndexChanged(streamIndex, channel); - } - ); - } - - notifyUpdateChannels(); -} - -void FreqScanner::handleChannelRemoved(int deviceSetIndex, ChannelAPI* channel) -{ - if (deviceSetIndex != getDeviceSetIndex()) { // Can control channels only in the same device set - return; - } - - qDebug("FreqScanner::handleChannelRemoved: deviceSetIndex: %d:%d channel: %s (%p)", - deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel); - DSPDeviceSourceEngine* deviceSourceEngine = getDeviceAPI()->getDeviceSourceEngine(); - DSPDeviceMIMOEngine *deviceMIMOEngine = getDeviceAPI()->getDeviceMIMOEngine(); - - if (deviceSourceEngine || deviceMIMOEngine) { - m_availableChannels.remove(channel); - } - - notifyUpdateChannels(); -} - -void FreqScanner::handleChannelStreamIndexChanged(int streamIndex, ChannelAPI* channel) -{ - qDebug("FreqScanner::handleChannelStreamIndexChanged: channel: %s (%p) stream: %d", - qPrintable(channel->getURI()), channel, streamIndex); - if (streamIndex != m_settings.m_streamIndex) // channel has moved to another I/Q stream - { - m_availableChannels.remove(channel); - notifyUpdateChannels(); - } - else if (!m_availableChannels.contains(channel)) // if channel has been tracked before put back it in the list - { - FreqScannerSettings::AvailableChannel availableChannel = - FreqScannerSettings::AvailableChannel{ - getDeviceSetIndex(), - channel->getIndexInDeviceSet(), - channel->getStreamIndex() - }; - m_availableChannels[channel] = availableChannel; - notifyUpdateChannels(); - } -} - -void FreqScanner::notifyUpdateChannels() +void FreqScanner::notifyUpdateChannels(const QStringList& renameFrom, const QStringList& renameTo) { if (getMessageQueueToGUI()) { - MsgReportChannels* msgToGUI = MsgReportChannels::create(); - QList& msgChannels = msgToGUI->getChannels(); - QHash::iterator it = m_availableChannels.begin(); - - for (; it != m_availableChannels.end(); ++it) - { - FreqScannerSettings::AvailableChannel msgChannel = - FreqScannerSettings::AvailableChannel{ - it->m_deviceSetIndex, - it->m_channelIndex, - it->m_streamIndex - }; - msgChannels.push_back(msgChannel); - } - + MsgReportChannels* msgToGUI = MsgReportChannels::create(renameFrom, renameTo); + msgToGUI->getChannels() = m_availableChannels; getMessageQueueToGUI()->push(msgToGUI); } } diff --git a/plugins/channelrx/freqscanner/freqscanner.h b/plugins/channelrx/freqscanner/freqscanner.h index 09a52c946..40f1fc84d 100644 --- a/plugins/channelrx/freqscanner/freqscanner.h +++ b/plugins/channelrx/freqscanner/freqscanner.h @@ -27,6 +27,7 @@ #include "dsp/basebandsamplesink.h" #include "channel/channelapi.h" #include "util/message.h" +#include "availablechannelorfeaturehandler.h" #include "freqscannerbaseband.h" #include "freqscannersettings.h" @@ -71,17 +72,23 @@ public: public: - QList& getChannels() { return m_channels; } + AvailableChannelOrFeatureList& getChannels() { return m_channels; } + const QStringList& getRenameFrom() const { return m_renameFrom; } + const QStringList& getRenameTo() const { return m_renameTo; } - static MsgReportChannels* create() { - return new MsgReportChannels(); + static MsgReportChannels* create(const QStringList& renameFrom, const QStringList& renameTo) { + return new MsgReportChannels(renameFrom, renameTo); } private: - QList m_channels; + AvailableChannelOrFeatureList m_channels; + QStringList m_renameFrom; + QStringList m_renameTo; - MsgReportChannels() : - Message() + MsgReportChannels(const QStringList& renameFrom, const QStringList& renameTo) : + Message(), + m_renameFrom(renameFrom), + m_renameTo(renameTo) {} }; @@ -369,7 +376,8 @@ private: QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; - QHash m_availableChannels; + AvailableChannelOrFeatureList m_availableChannels; + AvailableChannelOrFeatureHandler m_availableChannelHandler; unsigned int m_scanDeviceSetIndex; unsigned int m_scanChannelIndex; @@ -402,8 +410,8 @@ private: ); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); - void scanAvailableChannels(); - void notifyUpdateChannels(); + //void scanAvailableChannels(); + void notifyUpdateChannels(const QStringList& renameFrom, const QStringList& renameTo); void startScan(); void stopScan(); void initScan(); @@ -416,9 +424,7 @@ private: private slots: void networkManagerFinished(QNetworkReply *reply); void handleIndexInDeviceSetChanged(int index); - void handleChannelAdded(int deviceSetIndex, ChannelAPI* channel); - void handleChannelRemoved(int deviceSetIndex, ChannelAPI* channel); - void handleChannelStreamIndexChanged(int streamIndex, ChannelAPI* channel); + void channelsChanged(const QStringList& renameFrom, const QStringList& renameTo); void timeout(); }; diff --git a/plugins/channelrx/freqscanner/freqscannergui.cpp b/plugins/channelrx/freqscanner/freqscannergui.cpp index 71030f12b..68c92577a 100644 --- a/plugins/channelrx/freqscanner/freqscannergui.cpp +++ b/plugins/channelrx/freqscanner/freqscannergui.cpp @@ -118,8 +118,7 @@ bool FreqScannerGUI::handleMessage(const Message& message) else if (FreqScanner::MsgReportChannels::match(message)) { FreqScanner::MsgReportChannels& report = (FreqScanner::MsgReportChannels&)message; - m_availableChannels = report.getChannels(); - updateChannelsList(m_availableChannels); + updateChannelsList(report.getChannels(), report.getRenameFrom(), report.getRenameTo()); return true; } else if (FreqScanner::MsgStatus::match(message)) @@ -212,7 +211,7 @@ bool FreqScannerGUI::handleMessage(const Message& message) return false; } -void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QList& channels, const QString& channel, bool empty) +void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const AvailableChannelOrFeatureList& channels, const QString& channel, bool empty) { combo->blockSignals(true); combo->clear(); @@ -223,17 +222,8 @@ void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QListgetDeviceSetIndex()) && (channel.m_channelIndex != m_freqScanner->getIndexInDeviceSet())) - { - QString name; - - if (channel.m_streamIndex < 0) { // Rx - name = QString("R%1:%2").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex); - } else { // MIMO - name = QString("M%1:%2.%3").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex).arg(channel.m_streamIndex); - } - - combo->addItem(name); + if ((channel.m_superIndex == m_freqScanner->getDeviceSetIndex()) && (channel.m_index != m_freqScanner->getIndexInDeviceSet())) { + combo->addItem(channel.getId()); } } @@ -250,8 +240,29 @@ void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QListblockSignals(false); } -void FreqScannerGUI::updateChannelsList(const QList& channels) +void FreqScannerGUI::updateChannelsList(const AvailableChannelOrFeatureList& channels, const QStringList& renameFrom, const QStringList& renameTo) { + m_availableChannels = channels; + + // Update channel setting if it has been renamed + if (renameFrom.contains(m_settings.m_channel)) + { + m_settings.m_channel = renameTo[renameFrom.indexOf(m_settings.m_channel)]; + applySetting("channel"); + } + bool rename = false; + for (auto& setting : m_settings.m_frequencySettings) + { + if (renameFrom.contains(setting.m_channel)) + { + setting.m_channel = renameTo[renameFrom.indexOf(setting.m_channel)]; + rename = true; + } + } + if (rename) { + applySetting("frequencySettings"); + } + updateChannelsCombo(ui->channels, channels, m_settings.m_channel, false); for (int row = 0; row < ui->table->rowCount(); row++) @@ -515,10 +526,12 @@ void FreqScannerGUI::applySetting(const QString& settingsKey) void FreqScannerGUI::applySettings(const QStringList& settingsKeys, bool force) { + m_settingsKeys.append(settingsKeys); if (m_doApplySettings) { - FreqScanner::MsgConfigureFreqScanner* message = FreqScanner::MsgConfigureFreqScanner::create(m_settings, settingsKeys, force); + FreqScanner::MsgConfigureFreqScanner* message = FreqScanner::MsgConfigureFreqScanner::create(m_settings, m_settingsKeys, force); m_freqScanner->getInputMessageQueue()->push(message); + m_settingsKeys.clear(); } } diff --git a/plugins/channelrx/freqscanner/freqscannergui.h b/plugins/channelrx/freqscanner/freqscannergui.h index edc598950..4dc9dd484 100644 --- a/plugins/channelrx/freqscanner/freqscannergui.h +++ b/plugins/channelrx/freqscanner/freqscannergui.h @@ -73,6 +73,7 @@ private: ChannelMarker m_channelMarker; RollupState m_rollupState; FreqScannerSettings m_settings; + QList m_settingsKeys; qint64 m_deviceCenterFrequency; bool m_doApplySettings; @@ -82,7 +83,7 @@ private: QMenu *m_menu; - QList m_availableChannels; + AvailableChannelOrFeatureList m_availableChannels; explicit FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0); virtual ~FreqScannerGUI(); @@ -98,8 +99,8 @@ private: void addRow(const FreqScannerSettings::FrequencySettings& frequencySettings); void updateAnnotation(int row); void updateAnnotations(); - void updateChannelsCombo(QComboBox *combo, const QList& channels, const QString& channel, bool empty); - void updateChannelsList(const QList& channels); + void updateChannelsCombo(QComboBox *combo, const AvailableChannelOrFeatureList& channels, const QString& channel, bool empty); + void updateChannelsList(const AvailableChannelOrFeatureList& channels, const QStringList& renameFrom, const QStringList& renameTo); void setAllEnabled(bool enable); void leaveEvent(QEvent*); diff --git a/plugins/channelrx/freqscanner/freqscannersettings.h b/plugins/channelrx/freqscanner/freqscannersettings.h index 439f06419..a1ec26b0b 100644 --- a/plugins/channelrx/freqscanner/freqscannersettings.h +++ b/plugins/channelrx/freqscanner/freqscannersettings.h @@ -31,17 +31,6 @@ class ChannelAPI; struct FreqScannerSettings { - struct AvailableChannel - { - int m_deviceSetIndex; - int m_channelIndex; - int m_streamIndex; - - AvailableChannel() = default; - AvailableChannel(const AvailableChannel&) = default; - AvailableChannel& operator=(const AvailableChannel&) = default; - }; - struct FrequencySettings { qint64 m_frequency; bool m_enabled; diff --git a/plugins/channelrx/radioastronomy/radioastronomy.cpp b/plugins/channelrx/radioastronomy/radioastronomy.cpp index baa76f478..261d91c39 100644 --- a/plugins/channelrx/radioastronomy/radioastronomy.cpp +++ b/plugins/channelrx/radioastronomy/radioastronomy.cpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. // -// Copyright (C) 2021 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -67,10 +67,12 @@ const char * const RadioAstronomy::m_channelIdURI = "sdrangel.channel.radioastro const char * const RadioAstronomy::m_channelId = "RadioAstronomy"; RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) : - ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), - m_deviceAPI(deviceAPI), - m_basebandSampleRate(0), - m_sweeping(false) + ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink), + m_deviceAPI(deviceAPI), + m_basebandSampleRate(0), + m_sweeping(false), + m_availableFeatureHandler({"sdrangel.feature.startracker"}, QStringList{"startracker.target"}), + m_availableRotatorHandler({"sdrangel.feature.gs232controller"}) { qDebug("RadioAstronomy::RadioAstronomy"); setObjectName(m_channelId); @@ -105,17 +107,26 @@ RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) : &RadioAstronomy::handleIndexInDeviceSetChanged ); QObject::connect( - MainCore::instance(), - &MainCore::featureAdded, + &m_availableFeatureHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &RadioAstronomy::handleFeatureAdded + &RadioAstronomy::handleFeatureMessageQueue ); QObject::connect( - MainCore::instance(), - &MainCore::featureRemoved, + &m_availableFeatureHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, - &RadioAstronomy::handleFeatureRemoved + &RadioAstronomy::featuresChanged ); + m_availableFeatureHandler.scanAvailableChannelsAndFeatures(); + + QObject::connect( + &m_availableRotatorHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, + this, + &RadioAstronomy::rotatorsChanged + ); + m_availableRotatorHandler.scanAvailableChannelsAndFeatures(); m_sweepTimer.setSingleShot(true); } @@ -123,17 +134,20 @@ RadioAstronomy::RadioAstronomy(DeviceAPI *deviceAPI) : RadioAstronomy::~RadioAstronomy() { qDebug("RadioAstronomy::~RadioAstronomy"); - QObject::disconnect( - MainCore::instance(), - &MainCore::featureRemoved, + QObject::disconnect(&m_availableFeatureHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &RadioAstronomy::handleFeatureRemoved + &RadioAstronomy::handleFeatureMessageQueue ); - QObject::disconnect( - MainCore::instance(), - &MainCore::featureAdded, + QObject::disconnect(&m_availableFeatureHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, - &RadioAstronomy::handleFeatureAdded + &RadioAstronomy::featuresChanged + ); + QObject::disconnect(&m_availableRotatorHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, + this, + &RadioAstronomy::rotatorsChanged ); QObject::disconnect( m_networkManager, @@ -194,8 +208,6 @@ void RadioAstronomy::start() m_basebandSink->getInputMessageQueue()->push(new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency)); m_basebandSink->getInputMessageQueue()->push(RadioAstronomyBaseband::MsgConfigureRadioAstronomyBaseband::create(m_settings, true)); m_worker->getInputMessageQueue()->push(RadioAstronomyWorker::MsgConfigureRadioAstronomyWorker::create(m_settings, true)); - - scanAvailableFeatures(); } void RadioAstronomy::stop() @@ -330,7 +342,8 @@ bool RadioAstronomy::handleMessage(const Message& cmd) } else if (MsgScanAvailableFeatures::match(cmd)) { - scanAvailableFeatures(); + notifyUpdateFeatures({}, {}); + notifyUpdateRotators({}, {}); return true; } else @@ -753,22 +766,14 @@ void RadioAstronomy::applySettings(const RadioAstronomySettings& settings, bool { if (!settings.m_starTracker.isEmpty()) { - Feature *feature = nullptr; - - for (const auto& fval : m_availableFeatures) + int index = m_availableFeatures.indexOfLongId(settings.m_starTracker); + if (index >= 0) { - QString starTrackerText = tr("F%1:%2 %3").arg(fval.m_featureSetIndex).arg(fval.m_featureIndex).arg(fval.m_type); - - if (settings.m_starTracker == starTrackerText) - { - feature = m_availableFeatures.key(fval); - break; - } + m_selectedPipe = m_availableFeatures[index].m_object; } - - if (feature) { - m_selectedPipe = feature; - } else { + else + { + m_selectedPipe = nullptr; qDebug() << "RadioAstronomy::applySettings: No plugin corresponding to target " << settings.m_starTracker; } } @@ -1246,145 +1251,39 @@ void RadioAstronomy::handleIndexInDeviceSetChanged(int index) m_basebandSink->setFifoLabel(fifoLabel); } -void RadioAstronomy::scanAvailableFeatures() +void RadioAstronomy::featuresChanged(const QStringList& renameFrom, const QStringList& renameTo) { - qDebug("RadioAstronomy::scanAvailableFeatures"); - MainCore *mainCore = MainCore::instance(); - MessagePipes& messagePipes = mainCore->getMessagePipes(); - std::vector& 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(pipe->m_element); - QObject::connect( - messageQueue, - &MessageQueue::messageEnqueued, - this, - [=](){ this->handleFeatureMessageQueue(messageQueue); }, - Qt::QueuedConnection - ); - connect(pipe, SIGNAL(toBeDeleted(int, QObject*)), this, SLOT(handleMessagePipeToBeDeleted(int, QObject*))); - RadioAstronomySettings::AvailableFeature availableFeature = - RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()}; - m_availableFeatures[feature] = availableFeature; - } - } - else if (feature->getURI() == "sdrangel.feature.gs232controller") - { - RadioAstronomySettings::AvailableFeature rotator = - RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()}; - m_rotators[feature] = rotator; - } - } - } - - notifyUpdateFeatures(); - notifyUpdateRotators(); + m_availableFeatures = m_availableFeatureHandler.getAvailableChannelOrFeatureList(); + notifyUpdateFeatures(renameFrom, renameTo); } -void RadioAstronomy::notifyUpdateFeatures() + +void RadioAstronomy::notifyUpdateFeatures(const QStringList& renameFrom, const QStringList& renameTo) { if (getMessageQueueToGUI()) { - MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create(); - msg->getFeatures() = m_availableFeatures.values(); + MsgReportAvailableFeatures *msg = MsgReportAvailableFeatures::create(renameFrom, renameTo); + msg->getFeatures() = m_availableFeatures; getMessageQueueToGUI()->push(msg); } } -void RadioAstronomy::notifyUpdateRotators() +void RadioAstronomy::rotatorsChanged(const QStringList& renameFrom, const QStringList& renameTo) +{ + m_rotators = m_availableRotatorHandler.getAvailableChannelOrFeatureList(); + notifyUpdateRotators(renameFrom, renameTo); +} + +void RadioAstronomy::notifyUpdateRotators(const QStringList& renameFrom, const QStringList& renameTo) { if (getMessageQueueToGUI()) { - MsgReportAvailableRotators *msg = MsgReportAvailableRotators::create(); - msg->getFeatures() = m_rotators.values(); + MsgReportAvailableRotators *msg = MsgReportAvailableRotators::create(renameFrom, renameTo); + msg->getFeatures() = m_rotators; getMessageQueueToGUI()->push(msg); } } -void RadioAstronomy::handleFeatureAdded(int featureSetIndex, Feature *feature) -{ - qDebug("RadioAstronomy::handleFeatureAdded: featureSetIndex: %d:%d feature: %s (%p)", - featureSetIndex, feature->getIndexInFeatureSet(), qPrintable(feature->getURI()), feature); - FeatureSet *featureSet = MainCore::instance()->getFeatureeSets()[featureSetIndex]; - - if (RadioAstronomySettings::m_pipeURIs.contains(feature->getURI())) - { - int fei = feature->getIndexInFeatureSet(); - - if (!m_availableFeatures.contains(feature)) - { - MessagePipes& messagePipes = MainCore::instance()->getMessagePipes(); - ObjectPipe *pipe = messagePipes.registerProducerToConsumer(feature, this, "startracker.target"); - MessageQueue *messageQueue = qobject_cast(pipe->m_element); - QObject::connect( - messageQueue, - &MessageQueue::messageEnqueued, - this, - [=](){ this->handleFeatureMessageQueue(messageQueue); }, - Qt::QueuedConnection - ); - QObject::connect( - pipe, - &ObjectPipe::toBeDeleted, - this, - &RadioAstronomy::handleMessagePipeToBeDeleted - ); - } - - RadioAstronomySettings::AvailableFeature availableFeature = - RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()}; - m_availableFeatures[feature] = availableFeature; - - notifyUpdateFeatures(); - } - else if (feature->getURI() == "sdrangel.feature.gs232controller") - { - if (!m_rotators.contains(feature)) - { - RadioAstronomySettings::AvailableFeature rotator = - RadioAstronomySettings::AvailableFeature{featureSet->getIndex(), feature->getIndexInFeatureSet(), feature->getIdentifier()}; - m_rotators[feature] = rotator; - } - - notifyUpdateRotators(); - } -} - -void RadioAstronomy::handleFeatureRemoved(int featureSetIndex, Feature *feature) -{ - qDebug("RadioAstronomy::handleFeatureRemoved: featureSetIndex: %d (%p)", featureSetIndex, feature); - - if (m_rotators.contains(feature)) - { - m_rotators.remove(feature); - notifyUpdateRotators(); - } -} - -void RadioAstronomy::handleMessagePipeToBeDeleted(int reason, QObject* object) -{ - if ((reason == 0) && m_availableFeatures.contains((Feature*) object)) // producer (feature) - { - qDebug("RadioAstronomy::handleMessagePipeToBeDeleted: removing feature at (%p)", object); - m_availableFeatures.remove((Feature*) object); - notifyUpdateFeatures(); - } -} - void RadioAstronomy::handleFeatureMessageQueue(MessageQueue* messageQueue) { Message* message; diff --git a/plugins/channelrx/radioastronomy/radioastronomy.h b/plugins/channelrx/radioastronomy/radioastronomy.h index 1021f8590..bc1679bac 100644 --- a/plugins/channelrx/radioastronomy/radioastronomy.h +++ b/plugins/channelrx/radioastronomy/radioastronomy.h @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. // -// Copyright (C) 2021 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -31,6 +31,7 @@ #include "dsp/basebandsamplesink.h" #include "channel/channelapi.h" #include "util/message.h" +#include "availablechannelorfeaturehandler.h" #include "radioastronomybaseband.h" #include "radioastronomysettings.h" @@ -329,17 +330,23 @@ public: MESSAGE_CLASS_DECLARATION public: - QList& getFeatures() { return m_availableFeatures; } + AvailableChannelOrFeatureList& getFeatures() { return m_availableFeatures; } + const QStringList& getRenameFrom() const { return m_renameFrom; } + const QStringList& getRenameTo() const { return m_renameTo; } - static MsgReportAvailableFeatures* create() { - return new MsgReportAvailableFeatures(); + static MsgReportAvailableFeatures* create(const QStringList& renameFrom, const QStringList& renameTo) { + return new MsgReportAvailableFeatures(renameFrom, renameTo); } private: - QList m_availableFeatures; + AvailableChannelOrFeatureList m_availableFeatures; + QStringList m_renameFrom; + QStringList m_renameTo; - MsgReportAvailableFeatures() : - Message() + MsgReportAvailableFeatures(const QStringList& renameFrom, const QStringList& renameTo) : + Message(), + m_renameFrom(renameFrom), + m_renameTo(renameTo) {} }; @@ -347,17 +354,24 @@ public: MESSAGE_CLASS_DECLARATION public: - QList& getFeatures() { return m_availableFeatures; } + AvailableChannelOrFeatureList& getFeatures() { return m_availableFeatures; } + const QStringList& getRenameFrom() const { return m_renameFrom; } + const QStringList& getRenameTo() const { return m_renameTo; } - static MsgReportAvailableRotators* create() { - return new MsgReportAvailableRotators(); + + static MsgReportAvailableRotators* create(const QStringList& renameFrom, const QStringList& renameTo) { + return new MsgReportAvailableRotators(renameFrom, renameTo); } private: - QList m_availableFeatures; + AvailableChannelOrFeatureList m_availableFeatures; + QStringList m_renameFrom; + QStringList m_renameTo; - MsgReportAvailableRotators() : - Message() + MsgReportAvailableRotators(const QStringList& renameFrom, const QStringList& renameTo) : + Message(), + m_renameFrom(renameFrom), + m_renameTo(renameTo) {} }; @@ -448,8 +462,10 @@ private: int m_basebandSampleRate; //!< stored from device message used when starting baseband sink qint64 m_centerFrequency; - QHash m_availableFeatures; - QHash m_rotators; + AvailableChannelOrFeatureHandler m_availableFeatureHandler; + AvailableChannelOrFeatureList m_availableFeatures; + AvailableChannelOrFeatureHandler m_availableRotatorHandler; + AvailableChannelOrFeatureList m_rotators; QObject *m_selectedPipe; QNetworkAccessManager *m_networkManager; @@ -482,9 +498,8 @@ private: void sweepStart(); void startCal(bool hot); void calComplete(MsgCalComplete* report); - void scanAvailableFeatures(); - void notifyUpdateFeatures(); - void notifyUpdateRotators(); + void notifyUpdateFeatures(const QStringList& renameFrom, const QStringList& renameTo); + void notifyUpdateRotators(const QStringList& renameFrom, const QStringList& renameTo); private slots: void networkManagerFinished(QNetworkReply *reply); @@ -496,9 +511,8 @@ private slots: void sweepNext(); void sweepComplete(); void handleIndexInDeviceSetChanged(int index); - void handleFeatureAdded(int featureSetIndex, Feature *feature); - void handleFeatureRemoved(int featureSetIndex, Feature *feature); - void handleMessagePipeToBeDeleted(int reason, QObject* object); + void featuresChanged(const QStringList& renameFrom, const QStringList& renameTo); + void rotatorsChanged(const QStringList& renameFrom, const QStringList& renameTo); void handleFeatureMessageQueue(MessageQueue* messageQueue); }; diff --git a/plugins/channelrx/radioastronomy/radioastronomygui.cpp b/plugins/channelrx/radioastronomy/radioastronomygui.cpp index af8304c6b..1ccc60fb9 100644 --- a/plugins/channelrx/radioastronomy/radioastronomygui.cpp +++ b/plugins/channelrx/radioastronomy/radioastronomygui.cpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Edouard Griffiths, F4EXB // -// Copyright (C) 2021 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -916,31 +916,33 @@ bool RadioAstronomyGUI::deserialize(const QByteArray& data) } } -void RadioAstronomyGUI::updateAvailableFeatures() +void RadioAstronomyGUI::updateAvailableFeatures(const AvailableChannelOrFeatureList& availableFeatures, const QStringList& renameFrom, const QStringList& renameTo) { - QString currentText = ui->starTracker->currentText(); + // Update starTracker settting if it has been renamed + if (renameFrom.contains(m_settings.m_starTracker)) + { + m_settings.m_starTracker = renameTo[renameFrom.indexOf(m_settings.m_starTracker)]; + applySettings(); + } + ui->starTracker->blockSignals(true); ui->starTracker->clear(); - for (const auto& feature : m_availableFeatures) { - ui->starTracker->addItem(tr("F%1:%2 %3").arg(feature.m_featureSetIndex).arg(feature.m_featureIndex).arg(feature.m_type)); + for (const auto& feature : availableFeatures) { + ui->starTracker->addItem(feature.getLongId()); } - if (currentText.isEmpty()) - { - if (m_availableFeatures.size() > 0) { - ui->starTracker->setCurrentIndex(0); - } - } - else - { - ui->starTracker->setCurrentIndex(ui->starTracker->findText(currentText)); + int idx = ui->starTracker->findText(m_settings.m_starTracker); + if (idx >= 0) { + ui->starTracker->setCurrentIndex(idx); + } else { + ui->starTracker->setCurrentIndex(0); } ui->starTracker->blockSignals(false); - QString newText = ui->starTracker->currentText(); - if (currentText != newText) + QString newText = ui->starTracker->currentText(); + if (m_settings.m_starTracker != newText) { m_settings.m_starTracker = newText; applySettings(); @@ -970,8 +972,7 @@ bool RadioAstronomyGUI::handleMessage(const Message& message) { qDebug("RadioAstronomyGUI::handleMessage: MsgReportAvailableFeatures"); RadioAstronomy::MsgReportAvailableFeatures& report = (RadioAstronomy::MsgReportAvailableFeatures&) message; - m_availableFeatures = report.getFeatures(); - updateAvailableFeatures(); + updateAvailableFeatures(report.getFeatures(), report.getRenameFrom(), report.getRenameTo()); return true; } else if (MainCore::MsgStarTrackerTarget::match(message)) @@ -1063,7 +1064,7 @@ bool RadioAstronomyGUI::handleMessage(const Message& message) else if (RadioAstronomy::MsgReportAvailableRotators::match(message)) { RadioAstronomy::MsgReportAvailableRotators& report = (RadioAstronomy::MsgReportAvailableRotators&) message; - updateRotatorList(report.getFeatures()); + updateRotatorList(report.getFeatures(), report.getRenameFrom(), report.getRenameTo()); return true; } @@ -1901,11 +1902,11 @@ void RadioAstronomyGUI::on_loadSpectrumData_clicked() void RadioAstronomyGUI::on_powerTable_cellDoubleClicked(int row, int column) { - if ((column >= POWER_COL_RA) && (column >= POWER_COL_EL)) + if ((column >= POWER_COL_RA) && (column <= POWER_COL_EL)) { // Display target in Star Tracker QList starTrackerPipes; - MainCore::instance()->getMessagePipes().getMessagePipes(this, "startracker.display", starTrackerPipes); + MainCore::instance()->getMessagePipes().getMessagePipes(m_radioAstronomy, "startracker.display", starTrackerPipes); for (const auto& pipe : starTrackerPipes) { @@ -2604,17 +2605,22 @@ void RadioAstronomyGUI::tick() m_tickCount++; } -void RadioAstronomyGUI::updateRotatorList(const QList& rotators) +void RadioAstronomyGUI::updateRotatorList(const AvailableChannelOrFeatureList& rotators, const QStringList& renameFrom, const QStringList& renameTo) { + // Update rotator settting if it has been renamed + if (renameFrom.contains(m_settings.m_rotator)) + { + m_settings.m_rotator = renameTo[renameFrom.indexOf(m_settings.m_rotator)]; + applySettings(); + } + // Update list of rotators ui->rotator->blockSignals(true); ui->rotator->clear(); ui->rotator->addItem("None"); - for (const auto& rotator : rotators) - { - QString name = QString("F%1:%2 %3").arg(rotator.m_featureSetIndex).arg(rotator.m_featureIndex).arg(rotator.m_type); - ui->rotator->addItem(name); + for (const auto& rotator : rotators) { + ui->rotator->addItem(rotator.getLongId()); } // Rotator feature can be created after this plugin, so select it @@ -4335,7 +4341,7 @@ void RadioAstronomyGUI::updateLoSMarker(const QString& name, float l, float b, f { // Send to Star Tracker QList starTrackerPipes; - MainCore::instance()->getMessagePipes().getMessagePipes(this, "startracker.display", starTrackerPipes); + MainCore::instance()->getMessagePipes().getMessagePipes(m_radioAstronomy, "startracker.display", starTrackerPipes); for (const auto& pipe : starTrackerPipes) { @@ -4794,7 +4800,7 @@ void RadioAstronomyGUI::on_spectrumIndex_valueChanged(int value) // Display target in Star Tracker QList starTrackerPipes; - MainCore::instance()->getMessagePipes().getMessagePipes(this, "startracker.display", starTrackerPipes); + MainCore::instance()->getMessagePipes().getMessagePipes(m_radioAstronomy, "startracker.display", starTrackerPipes); for (const auto& pipe : starTrackerPipes) { diff --git a/plugins/channelrx/radioastronomy/radioastronomygui.h b/plugins/channelrx/radioastronomy/radioastronomygui.h index 9c59404a8..a391a9eb1 100644 --- a/plugins/channelrx/radioastronomy/radioastronomygui.h +++ b/plugins/channelrx/radioastronomy/radioastronomygui.h @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Edouard Griffiths, F4EXB // -// Copyright (C) 2021 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -235,7 +235,6 @@ private: RollupState m_rollupState; RadioAstronomySettings m_settings; bool m_doApplySettings; - QList m_availableFeatures; int m_basebandSampleRate; quint64 m_centerFrequency; @@ -351,8 +350,8 @@ private: void displaySettings(); void displaySpectrumLineFrequency(); void displayRunModeSettings(); - void updateAvailableFeatures(); - void updateRotatorList(const QList& rotators); + void updateAvailableFeatures(const AvailableChannelOrFeatureList& availableFeatures, const QStringList& renameFrom, const QStringList& renameTo); + void updateRotatorList(const AvailableChannelOrFeatureList& rotators, const QStringList& renameFrom, const QStringList& renameTo); bool handleMessage(const Message& message); void makeUIConnections(); void updateAbsoluteCenterFrequency(); diff --git a/plugins/channelrx/radioastronomy/radioastronomysettings.cpp b/plugins/channelrx/radioastronomy/radioastronomysettings.cpp index dfb924fd1..953aec450 100644 --- a/plugins/channelrx/radioastronomy/radioastronomysettings.cpp +++ b/plugins/channelrx/radioastronomy/radioastronomysettings.cpp @@ -23,14 +23,6 @@ #include "settings/serializable.h" #include "radioastronomysettings.h" -const QStringList RadioAstronomySettings::m_pipeTypes = { - QStringLiteral("StarTracker") -}; - -const QStringList RadioAstronomySettings::m_pipeURIs = { - QStringLiteral("sdrangel.feature.startracker") -}; - RadioAstronomySettings::RadioAstronomySettings() : m_channelMarker(nullptr), m_rollupState(nullptr) diff --git a/plugins/channelrx/radioastronomy/radioastronomysettings.h b/plugins/channelrx/radioastronomy/radioastronomysettings.h index 02f8e447a..509bb9048 100644 --- a/plugins/channelrx/radioastronomy/radioastronomysettings.h +++ b/plugins/channelrx/radioastronomy/radioastronomysettings.h @@ -35,20 +35,6 @@ class Serializable; struct RadioAstronomySettings { - struct AvailableFeature - { - int m_featureSetIndex; - int m_featureIndex; - QString m_type; - - AvailableFeature() = default; - AvailableFeature(const AvailableFeature&) = default; - AvailableFeature& operator=(const AvailableFeature&) = default; - bool operator==(const AvailableFeature& a) const { - return (m_featureSetIndex == a.m_featureSetIndex) && (m_featureIndex == a.m_featureIndex) && (m_type == a.m_type); - } - }; - int m_inputFrequencyOffset; int m_sampleRate; int m_rfBandwidth; @@ -244,9 +230,6 @@ struct RadioAstronomySettings void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; } QByteArray serialize() const; bool deserialize(const QByteArray& data); - - static const QStringList m_pipeTypes; - static const QStringList m_pipeURIs; }; #endif /* INCLUDE_RADIOASTRONOMYSETTINGS_H */ diff --git a/plugins/feature/ais/ais.cpp b/plugins/feature/ais/ais.cpp index aca0bf9e0..484b9a32a 100644 --- a/plugins/feature/ais/ais.cpp +++ b/plugins/feature/ais/ais.cpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2021-2022 Edouard Griffiths, F4EXB // -// Copyright (C) 2021 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -41,7 +41,8 @@ const char* const AIS::m_featureIdURI = "sdrangel.feature.ais"; const char* const AIS::m_featureId = "AIS"; AIS::AIS(WebAPIAdapterInterface *webAPIAdapterInterface) : - Feature(m_featureIdURI, webAPIAdapterInterface) + Feature(m_featureIdURI, webAPIAdapterInterface), + m_availableChannelHandler({"sdrangel.channel.aisdemod"}, QStringList{"ais"}) { qDebug("AIS::AIS: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); @@ -54,23 +55,20 @@ AIS::AIS(WebAPIAdapterInterface *webAPIAdapterInterface) : this, &AIS::networkManagerFinished ); - scanAvailableChannels(); QObject::connect( - MainCore::instance(), - &MainCore::channelAdded, + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &AIS::handleChannelAdded - ); + &AIS::handleChannelMessageQueue); } AIS::~AIS() { QObject::disconnect( - MainCore::instance(), - &MainCore::channelAdded, + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &AIS::handleChannelAdded - ); + &AIS::handleChannelMessageQueue); QObject::disconnect( m_networkManager, &QNetworkAccessManager::finished, @@ -362,90 +360,6 @@ void AIS::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } -void AIS::scanAvailableChannels() -{ - MainCore *mainCore = MainCore::instance(); - MessagePipes& messagePipes = mainCore->getMessagePipes(); - std::vector& 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(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& 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(pipe->m_element); - QObject::connect( - messageQueue, - &MessageQueue::messageEnqueued, - this, - [=](){ this->handleChannelMessageQueue(messageQueue); }, - Qt::QueuedConnection - ); - QObject::connect( - pipe, - &ObjectPipe::toBeDeleted, - this, - &AIS::handleMessagePipeToBeDeleted - ); - m_availableChannels.insert(channel); - } - } -} - -void AIS::handleMessagePipeToBeDeleted(int reason, QObject* object) -{ - if ((reason == 0) && m_availableChannels.contains((ChannelAPI*) object)) // producer (channel) - { - qDebug("AIS::handleMessagePipeToBeDeleted: removing channel at (%p)", object); - m_availableChannels.remove((ChannelAPI*) object); - } -} - void AIS::handleChannelMessageQueue(MessageQueue* messageQueue) { Message* message; diff --git a/plugins/feature/ais/ais.h b/plugins/feature/ais/ais.h index 937ab54a4..ae089d074 100644 --- a/plugins/feature/ais/ais.h +++ b/plugins/feature/ais/ais.h @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB // // Copyright (C) 2020 Kacper Michajłow // -// Copyright (C) 2021-2022 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -25,6 +25,7 @@ #include "feature/feature.h" #include "util/message.h" +#include "availablechannelorfeaturehandler.h" #include "aissettings.h" @@ -101,7 +102,8 @@ public: private: AISSettings m_settings; - QSet m_availableChannels; + AvailableChannelOrFeatureHandler m_availableChannelHandler; + AvailableChannelOrFeatureList m_availableChannels; QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; @@ -110,12 +112,9 @@ private: void stop(); void applySettings(const AISSettings& settings, const QList& settingsKeys, bool force = false); void webapiReverseSendSettings(const QList& featureSettingsKeys, const AISSettings& settings, bool force); - void scanAvailableChannels(); private slots: void networkManagerFinished(QNetworkReply *reply); - void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel); - void handleMessagePipeToBeDeleted(int reason, QObject* object); void handleChannelMessageQueue(MessageQueue* messageQueue); }; diff --git a/plugins/feature/ais/aisgui.cpp b/plugins/feature/ais/aisgui.cpp index 05945886d..9ce611f6a 100644 --- a/plugins/feature/ais/aisgui.cpp +++ b/plugins/feature/ais/aisgui.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2021-2023 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // Copyright (C) 2021-2022 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // @@ -47,7 +47,7 @@ QStringList AISGUI::m_shipModels = { "tug_20m.glbe", "tug_30m_1.glbe", "tug_30m_2.glbe", "tug_30m_3.glbe", "cargo_75m.glbe", "tanker_50m.glbe", "dredger_53m.glbe", "trawler_22m.glbe", - "speedboat_8m.glbe", "yacht_10m.glbe", "yacht_20m.glbe", "yacht_42m.glbe" + "speedboat_8m.glbe", /*"yacht_10m.glbe",*/ "yacht_20m.glbe", "yacht_42m.glbe" }; QStringList AISGUI::m_sailboatModels = { @@ -236,6 +236,7 @@ AISGUI::AISGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur displaySettings(); applySettings(true); + m_resizer.enableChildMouseTracking(); } AISGUI::~AISGUI() @@ -845,14 +846,14 @@ void AISGUI::getImageAndModel(const QString &type, const QString &shipType, int { vessel->m_model = "cargo_75m.glbe"; } - else if (length < 200) + else /*if (length < 200)*/ { vessel->m_model = "cargo_190m.glbe"; } - else + /*else { vessel->m_model = "cargo_230m.glbe"; - } + }*/ } else if (shipType == "Tanker") { @@ -905,10 +906,10 @@ void AISGUI::getImageAndModel(const QString &type, const QString &shipType, int { vessel->m_model = "speedboat_8m.glbe"; } - else if (length < 18) + /*else if (length < 18) { vessel->m_model = "yacht_10m.glbe"; - } + }*/ else if (length < 32) { vessel->m_model = "yacht_20m.glbe"; diff --git a/plugins/feature/aprs/aprs.cpp b/plugins/feature/aprs/aprs.cpp index 4c6ed9583..8bd06c23a 100644 --- a/plugins/feature/aprs/aprs.cpp +++ b/plugins/feature/aprs/aprs.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2021-2023 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // Copyright (C) 2021-2022 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // @@ -46,7 +46,8 @@ const char* const APRS::m_featureId = "APRS"; APRS::APRS(WebAPIAdapterInterface *webAPIAdapterInterface) : Feature(m_featureIdURI, webAPIAdapterInterface), m_thread(nullptr), - m_worker(nullptr) + m_worker(nullptr), + m_availableChannelHandler(APRSSettings::m_pipeURIs, QStringList{"packets"}) { qDebug("APRS::APRS: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); @@ -59,23 +60,31 @@ APRS::APRS(WebAPIAdapterInterface *webAPIAdapterInterface) : this, &APRS::networkManagerFinished ); - scanAvailableChannels(); QObject::connect( - MainCore::instance(), - &MainCore::channelAdded, + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &APRS::handleChannelAdded - ); + &APRS::handleChannelMessageQueue); + QObject::connect( + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, + this, + &APRS::channelsChanged); + m_availableChannelHandler.scanAvailableChannelsAndFeatures(); } APRS::~APRS() { QObject::disconnect( - MainCore::instance(), - &MainCore::channelAdded, + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &APRS::handleChannelAdded - ); + &APRS::handleChannelMessageQueue); + QObject::disconnect( + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, + this, + &APRS::channelsChanged); QObject::disconnect( m_networkManager, &QNetworkAccessManager::finished, @@ -858,6 +867,7 @@ void APRS::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } +/* void APRS::scanAvailableChannels() { MainCore *mainCore = MainCore::instance(); @@ -905,18 +915,25 @@ void APRS::scanAvailableChannels() } } } +*/ + +void APRS::channelsChanged() +{ + m_availableChannels = m_availableChannelHandler.getAvailableChannelOrFeatureList(); + notifyUpdateChannels(); +} void APRS::notifyUpdateChannels() { if (getMessageQueueToGUI()) { MsgReportAvailableChannels *msg = MsgReportAvailableChannels::create(); - msg->getChannels() = m_availableChannels.values(); + msg->getChannels() = m_availableChannels; getMessageQueueToGUI()->push(msg); } } -void APRS::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel) +/*void APRS::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel) { qDebug("APRS::handleChannelAdded: deviceSetIndex: %d:%d channel: %s (%p)", deviceSetIndex, channel->getIndexInDeviceSet(), qPrintable(channel->getURI()), channel); @@ -964,7 +981,7 @@ void APRS::handleMessagePipeToBeDeleted(int reason, QObject* object) m_availableChannels.remove((ChannelAPI*) object); notifyUpdateChannels(); } -} +}*/ void APRS::handleChannelMessageQueue(MessageQueue* messageQueue) { diff --git a/plugins/feature/aprs/aprs.h b/plugins/feature/aprs/aprs.h index 8db360d15..a5de2ac55 100644 --- a/plugins/feature/aprs/aprs.h +++ b/plugins/feature/aprs/aprs.h @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB // // Copyright (C) 2020 Kacper Michajłow // -// Copyright (C) 2021-2022 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -26,6 +26,7 @@ #include "feature/feature.h" #include "util/message.h" +#include "availablechannelorfeaturehandler.h" #include "aprssettings.h" @@ -104,14 +105,14 @@ public: MESSAGE_CLASS_DECLARATION public: - QList& getChannels() { return m_availableChannels; } + AvailableChannelOrFeatureList& getChannels() { return m_availableChannels; } static MsgReportAvailableChannels* create() { return new MsgReportAvailableChannels(); } private: - QList m_availableChannels; + AvailableChannelOrFeatureList m_availableChannels; MsgReportAvailableChannels() : Message() @@ -160,7 +161,8 @@ private: QThread *m_thread; APRSWorker *m_worker; APRSSettings m_settings; - QHash m_availableChannels; + AvailableChannelOrFeatureHandler m_availableChannelHandler; + AvailableChannelOrFeatureList m_availableChannels; QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; @@ -169,14 +171,12 @@ private: void stop(); void applySettings(const APRSSettings& settings, const QList& settingsKeys, bool force = false); void webapiReverseSendSettings(const QList& featureSettingsKeys, const APRSSettings& settings, bool force); - void scanAvailableChannels(); void notifyUpdateChannels(); private slots: void networkManagerFinished(QNetworkReply *reply); - void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel); - void handleMessagePipeToBeDeleted(int reason, QObject* object); void handleChannelMessageQueue(MessageQueue* messageQueue); + void channelsChanged(); }; #endif // INCLUDE_FEATURE_APRS_H_ diff --git a/plugins/feature/aprs/aprsgui.cpp b/plugins/feature/aprs/aprsgui.cpp index cc1ffa936..4abcdd5b2 100644 --- a/plugins/feature/aprs/aprsgui.cpp +++ b/plugins/feature/aprs/aprsgui.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2021-2023 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // Copyright (C) 2022 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // @@ -708,7 +708,7 @@ void APRSGUI::updateChannelList() ui->sourcePipes->clear(); for (const auto& channel : m_availableChannels) { - ui->sourcePipes->addItem(tr("R%1:%2 %3").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex).arg(channel.m_type)); + ui->sourcePipes->addItem(channel.getLongId()); } ui->sourcePipes->blockSignals(false); diff --git a/plugins/feature/aprs/aprsgui.h b/plugins/feature/aprs/aprsgui.h index 148fe0a86..abc301ac8 100644 --- a/plugins/feature/aprs/aprsgui.h +++ b/plugins/feature/aprs/aprsgui.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2021-2023 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // Copyright (C) 2022 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // @@ -30,6 +30,7 @@ #include "util/messagequeue.h" #include "util/aprs.h" #include "settings/rollupstate.h" +#include "availablechannelorfeature.h" #include "aprssettings.h" @@ -123,7 +124,7 @@ private: QList m_settingsKeys; RollupState m_rollupState; bool m_doApplySettings; - QList m_availableChannels; + AvailableChannelOrFeatureList m_availableChannels; APRS* m_aprs; MessageQueue m_inputMessageQueue; diff --git a/plugins/feature/aprs/aprssettings.h b/plugins/feature/aprs/aprssettings.h index 1afc1ada0..4117df599 100644 --- a/plugins/feature/aprs/aprssettings.h +++ b/plugins/feature/aprs/aprssettings.h @@ -2,7 +2,7 @@ // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany // // written by Christian Daniel // // Copyright (C) 2015-2020, 2022 Edouard Griffiths, F4EXB // -// Copyright (C) 2020-2021 Jon Beniston, M7RCE // +// Copyright (C) 2020-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -38,17 +38,6 @@ class Serializable; struct APRSSettings { - struct AvailableChannel - { - int m_deviceSetIndex; - int m_channelIndex; - QString m_type; - - AvailableChannel() = default; - AvailableChannel(const AvailableChannel&) = default; - AvailableChannel& operator=(const AvailableChannel&) = default; - }; - QString m_igateServer; int m_igatePort; QString m_igateCallsign; diff --git a/plugins/feature/aprs/readme.md b/plugins/feature/aprs/readme.md index f81f4b0bf..39125f2ff 100644 --- a/plugins/feature/aprs/readme.md +++ b/plugins/feature/aprs/readme.md @@ -48,4 +48,4 @@ APRS icons are from: https://github.com/hessu/aprs-symbols Full details of the API can be found in the Swagger documentation. Here is a quick example of how to enable the APRS-IS IGate: - curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "APRS", "APRSSettings": { "igateCallsign": "MYCALLSIGN", "igatePasscode": "12345", "igateFilter": "r/50.2/10.2/25", "igateEnabled": 1 }}' + curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "APRS", "APRSSettings": { "igateCallsign": "MYCALLSIGN", "igatePasscode": "12345", "igateFilter": "r/50.2/10.2/25", "igateEnabled": 1 }}' diff --git a/plugins/feature/gs232controller/gs232controller.cpp b/plugins/feature/gs232controller/gs232controller.cpp index 9697d81b0..bc7399006 100644 --- a/plugins/feature/gs232controller/gs232controller.cpp +++ b/plugins/feature/gs232controller/gs232controller.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2020-2023 Jon Beniston, M7RCE // +// Copyright (C) 2020-2024 Jon Beniston, M7RCE // // Copyright (C) 2020-2022 Edouard Griffiths, F4EXB // // Copyright (C) 2020 Kacper Michajłow // // // @@ -56,6 +56,8 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface) Feature(m_featureIdURI, webAPIAdapterInterface), m_thread(nullptr), m_worker(nullptr), + m_availableChannelOrFeatureHandler(GS232ControllerSettings::m_pipeURIs), + m_selectedPipe(nullptr), m_currentAzimuth(0.0f), m_currentElevation(0.0f) { @@ -63,7 +65,6 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface) setObjectName(m_featureId); m_state = StIdle; m_errorMessage = "GS232Controller error"; - m_selectedPipe = nullptr; m_networkManager = new QNetworkAccessManager(); QObject::connect( m_networkManager, @@ -71,30 +72,21 @@ GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface) this, &GS232Controller::networkManagerFinished ); + QObject::connect( - MainCore::instance(), - &MainCore::featureAdded, + &m_availableChannelOrFeatureHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, - &GS232Controller::handleFeatureAdded + &GS232Controller::channelsOrFeaturesChanged ); QObject::connect( - MainCore::instance(), - &MainCore::channelAdded, + &m_availableChannelOrFeatureHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &GS232Controller::handleChannelAdded - ); - QObject::connect( - MainCore::instance(), - &MainCore::featureRemoved, - this, - &GS232Controller::handleFeatureRemoved - ); - QObject::connect( - MainCore::instance(), - &MainCore::channelRemoved, - this, - &GS232Controller::handleChannelRemoved + &GS232Controller::handlePipeMessageQueue ); + m_availableChannelOrFeatureHandler.scanAvailableChannelsAndFeatures(); + connect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts); m_timer.start(5000); } @@ -104,28 +96,16 @@ GS232Controller::~GS232Controller() m_timer.stop(); disconnect(&m_timer, &QTimer::timeout, this, &GS232Controller::scanSerialPorts); QObject::disconnect( - MainCore::instance(), - &MainCore::channelRemoved, + &m_availableChannelOrFeatureHandler, + &AvailableChannelOrFeatureHandler::channelsOrFeaturesChanged, this, - &GS232Controller::handleChannelRemoved + &GS232Controller::channelsOrFeaturesChanged ); QObject::disconnect( - MainCore::instance(), - &MainCore::featureRemoved, + &m_availableChannelOrFeatureHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &GS232Controller::handleFeatureRemoved - ); - QObject::disconnect( - MainCore::instance(), - &MainCore::channelAdded, - this, - &GS232Controller::handleChannelAdded - ); - QObject::disconnect( - MainCore::instance(), - &MainCore::featureAdded, - this, - &GS232Controller::handleFeatureAdded + &GS232Controller::handlePipeMessageQueue ); QObject::disconnect( m_networkManager, @@ -154,8 +134,6 @@ void GS232Controller::start() GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg = GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(m_settings, QList(), true); m_worker->getInputMessageQueue()->push(msg); - - scanAvailableChannelsAndFeatures(); } void GS232Controller::stop() @@ -210,7 +188,7 @@ bool GS232Controller::handleMessage(const Message& cmd) } else if (MsgScanAvailableChannelOrFeatures::match(cmd)) { - scanAvailableChannelsAndFeatures(); + notifyUpdate({}, {}); return true; } else if (GS232ControllerReport::MsgReportAzAl::match(cmd)) @@ -248,8 +226,6 @@ bool GS232Controller::handleMessage(const Message& cmd) applySettings(m_settings, QList{"azimuth", "elevation"}); } } - else - qDebug() << "GS232Controller::handleMessage: No match " << msg.getPipeSource() << " " << m_selectedPipe; } return true; } @@ -306,10 +282,6 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con { qDebug() << "GS232Controller::applySettings:" << settings.getDebugString(settingsKeys, force) << " force: " << force; - // if ((m_settings.m_source != settings.m_source) - // || (!settings.m_source.isEmpty() && (m_selectedPipe == nullptr)) // Change in available pipes - // || force) - if (settingsKeys.contains("source") || (!settings.m_source.isEmpty() && (m_selectedPipe == nullptr)) // Change in available pipes || force) @@ -317,27 +289,24 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con MainCore *mainCore = MainCore::instance(); MessagePipes& messagePipes = mainCore->getMessagePipes(); - if (m_selectedPipe) + m_availableChannelOrFeatureHandler.deregisterPipes(m_selectedPipe, this, {"target"}); + + /*if (m_selectedPipe) { - qDebug("GS232Controller::applySettings: unregister %s (%p)", qPrintable(m_selectedPipe->objectName()), m_selectedPipe); + // Don't deref m_selectedPipe, as plugin may have been deleted + qDebug("GS232Controller::applySettings: unregister (%p)", m_selectedPipe); messagePipes.unregisterProducerToConsumer(m_selectedPipe, this, "target"); - } + }*/ - if (!settings.m_source.isEmpty()) + m_selectedPipe = m_availableChannelOrFeatureHandler.registerPipes(settings.m_source, this, {"target"}); + + /*if (!settings.m_source.isEmpty()) { - QObject *object = nullptr; + int index = m_availableChannelOrFeatures.indexOfLongId(settings.m_source); - for (const auto& oval : m_availableChannelOrFeatures) - { - if (settings.m_source == oval.getLongId()) - { - object = oval.m_object; - break; - } - } - - if (object) + if (index >= 0) { + QObject *object = m_availableChannelOrFeatures[index].m_object; registerPipe(object); m_selectedPipe = object; } @@ -350,7 +319,7 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, con else { m_selectedPipe = nullptr; - } + }*/ } GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg = GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create( @@ -718,12 +687,7 @@ void GS232Controller::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& r for (const auto& item : m_availableChannelOrFeatures) { - QString itemText = tr("%1%2:%3 %4") - .arg(item.m_kind) - .arg(item.m_superIndex) - .arg(item.m_index) - .arg(item.m_type); - + QString itemText = item.getLongId(); response.getGs232ControllerReport()->getSources()->append(new QString(itemText)); } @@ -763,69 +727,22 @@ void GS232Controller::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } -void GS232Controller::scanAvailableChannelsAndFeatures() +void GS232Controller::channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo) { - m_availableChannelOrFeatures = MainCore::instance()->getAvailableChannelsAndFeatures(GS232ControllerSettings::m_pipeURIs); - notifyUpdate(); + m_availableChannelOrFeatures = m_availableChannelOrFeatureHandler.getAvailableChannelOrFeatureList(); + notifyUpdate(renameFrom, renameTo); } -void GS232Controller::notifyUpdate() +void GS232Controller::notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo) { if (getMessageQueueToGUI()) { - MsgReportAvailableChannelOrFeatures *msg = MsgReportAvailableChannelOrFeatures::create(); + MsgReportAvailableChannelOrFeatures *msg = MsgReportAvailableChannelOrFeatures::create(renameFrom, renameTo); msg->getItems() = m_availableChannelOrFeatures; getMessageQueueToGUI()->push(msg); } } -void GS232Controller::handleFeatureAdded(int featureSetIndex, Feature *feature) -{ - (void) featureSetIndex; - (void) feature; - - scanAvailableChannelsAndFeatures(); -} - -void GS232Controller::handleFeatureRemoved(int featureSetIndex, Feature *feature) -{ - (void) featureSetIndex; - (void) feature; - - scanAvailableChannelsAndFeatures(); -} - -void GS232Controller::handleChannelAdded(int deviceSetIndex, ChannelAPI *channel) -{ - (void) deviceSetIndex; - (void) channel; - - scanAvailableChannelsAndFeatures(); -} - -void GS232Controller::handleChannelRemoved(int deviceSetIndex, ChannelAPI *channel) -{ - (void) deviceSetIndex; - (void) channel; - - scanAvailableChannelsAndFeatures(); -} - -void GS232Controller::registerPipe(QObject *object) -{ - qDebug("GS232Controller::registerPipe: register %s (%p)", qPrintable(object->objectName()), object); - MessagePipes& messagePipes = MainCore::instance()->getMessagePipes(); - ObjectPipe *pipe = messagePipes.registerProducerToConsumer(object, this, "target"); - MessageQueue *messageQueue = qobject_cast(pipe->m_element); - QObject::connect( - messageQueue, - &MessageQueue::messageEnqueued, - this, - [=](){ this->handlePipeMessageQueue(messageQueue); }, - Qt::QueuedConnection - ); -} - void GS232Controller::handlePipeMessageQueue(MessageQueue* messageQueue) { Message* message; diff --git a/plugins/feature/gs232controller/gs232controller.h b/plugins/feature/gs232controller/gs232controller.h index 5972ee23b..83cd3272d 100644 --- a/plugins/feature/gs232controller/gs232controller.h +++ b/plugins/feature/gs232controller/gs232controller.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2020-2023 Jon Beniston, M7RCE // +// Copyright (C) 2020-2024 Jon Beniston, M7RCE // // Copyright (C) 2020-2022 Edouard Griffiths, F4EXB // // Copyright (C) 2020 Kacper Michajłow // // // @@ -27,6 +27,7 @@ #include "feature/feature.h" #include "util/message.h" +#include "availablechannelorfeaturehandler.h" #include "maincore.h" #include "gs232controllersettings.h" @@ -111,17 +112,23 @@ public: MESSAGE_CLASS_DECLARATION public: - QList& getItems() { return m_availableChannelOrFeatures; } + AvailableChannelOrFeatureList& getItems() { return m_availableChannelOrFeatures; } + const QStringList& getRenameFrom() const { return m_renameFrom; } + const QStringList& getRenameTo() const { return m_renameTo; } - static MsgReportAvailableChannelOrFeatures* create() { - return new MsgReportAvailableChannelOrFeatures(); + static MsgReportAvailableChannelOrFeatures* create(const QStringList& renameFrom, const QStringList& renameTo) { + return new MsgReportAvailableChannelOrFeatures(renameFrom, renameTo); } private: - QList m_availableChannelOrFeatures; + AvailableChannelOrFeatureList m_availableChannelOrFeatures; + QStringList m_renameFrom; + QStringList m_renameTo; - MsgReportAvailableChannelOrFeatures() : - Message() + MsgReportAvailableChannelOrFeatures(const QStringList& renameFrom, const QStringList& renameTo) : + Message(), + m_renameFrom(renameFrom), + m_renameTo(renameTo) {} }; @@ -213,8 +220,8 @@ private: QThread *m_thread; GS232ControllerWorker *m_worker; GS232ControllerSettings m_settings; - //QHash m_availableChannelOrFeatures; - QList m_availableChannelOrFeatures; + AvailableChannelOrFeatureList m_availableChannelOrFeatures; + AvailableChannelOrFeatureHandler m_availableChannelOrFeatureHandler; QObject *m_selectedPipe; QTimer m_timer; @@ -231,17 +238,11 @@ private: void applySettings(const GS232ControllerSettings& settings, const QList& settingsKeys, bool force = false); void webapiReverseSendSettings(const QList& featureSettingsKeys, const GS232ControllerSettings& settings, bool force); void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response); - void scanAvailableChannelsAndFeatures(); - void notifyUpdate(); - void registerPipe(QObject *object); + void notifyUpdate(const QStringList& renameFrom, const QStringList& renameTo); private slots: void networkManagerFinished(QNetworkReply *reply); - void handleFeatureAdded(int featureSetIndex, Feature *feature); - void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel); - void handleFeatureRemoved(int featureSetIndex, Feature *feature); - void handleChannelRemoved(int deviceSetIndex, ChannelAPI *feature); - //void handleMessagePipeToBeDeleted(int reason, QObject* object); + void channelsOrFeaturesChanged(const QStringList& renameFrom, const QStringList& renameTo); void handlePipeMessageQueue(MessageQueue* messageQueue); void scanSerialPorts(); }; diff --git a/plugins/feature/gs232controller/gs232controllergui.cpp b/plugins/feature/gs232controller/gs232controllergui.cpp index 7a32ab0c5..6c9477310 100644 --- a/plugins/feature/gs232controller/gs232controllergui.cpp +++ b/plugins/feature/gs232controller/gs232controllergui.cpp @@ -51,7 +51,7 @@ void GS232ControllerGUI::resetToDefaults() { m_settings.resetToDefaults(); displaySettings(); - applySettings(true); + applyAllSettings(); } QByteArray GS232ControllerGUI::serialize() const @@ -65,7 +65,7 @@ bool GS232ControllerGUI::deserialize(const QByteArray& data) { m_feature->setWorkspaceIndex(m_settings.m_workspaceIndex); displaySettings(); - applySettings(true); + applyAllSettings(); return true; } else @@ -121,9 +121,7 @@ void GS232ControllerGUI::displayToAzEl(float coord1, float coord2) m_settings.m_azimuth = coord1; m_settings.m_elevation = coord2; } - m_settingsKeys.append("azimuth"); - m_settingsKeys.append("elevation"); - applySettings(); + applySettings({"azimuth", "elevation"}); } bool GS232ControllerGUI::handleMessage(const Message& message) @@ -149,7 +147,7 @@ bool GS232ControllerGUI::handleMessage(const Message& message) { GS232Controller::MsgReportAvailableChannelOrFeatures& report = (GS232Controller::MsgReportAvailableChannelOrFeatures&) message; - updatePipeList(report.getItems()); + updatePipeList(report.getItems(), report.getRenameFrom(), report.getRenameTo()); return true; } else if (GS232ControllerReport::MsgReportAzAl::match(message)) @@ -206,7 +204,7 @@ void GS232ControllerGUI::onWidgetRolled(QWidget* widget, bool rollDown) (void) rollDown; getRollupContents()->saveState(m_rollupState); - applySettings(); + applySetting("rollupState"); } GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : @@ -260,7 +258,7 @@ GS232ControllerGUI::GS232ControllerGUI(PluginAPI* pluginAPI, FeatureUISet *featu connect(&m_inputTimer, &QTimer::timeout, this, &GS232ControllerGUI::checkInputController); displaySettings(); - applySettings(true); + applyAllSettings(); makeUIConnections(); // Get pre-existing pipes @@ -408,8 +406,7 @@ void GS232ControllerGUI::on_inputController_currentIndexChanged(int index) if (index >= 0) { m_settings.m_inputController = ui->inputController->currentText(); - m_settingsKeys.append("inputController"); - applySettings(); + applySetting("inputController"); updateInputController(); } } @@ -425,28 +422,24 @@ void GS232ControllerGUI::on_highSensitivity_clicked(bool checked) { m_settings.m_highSensitivity = checked; ui->highSensitivity->setText(checked ? "H" : "L"); - m_settingsKeys.append("highSensitivity"); - applySettings(); + applySetting("highSensitivity"); } void GS232ControllerGUI::on_enableTargetControl_clicked(bool checked) { m_settings.m_targetControlEnabled = checked; - m_settingsKeys.append("targetControlEnabled"); - applySettings(); + applySetting("targetControlEnabled"); } void GS232ControllerGUI::on_enableOffsetControl_clicked(bool checked) { m_settings.m_offsetControlEnabled = checked; - m_settingsKeys.append("offsetControlEnabled"); - applySettings(); + applySetting("offsetControlEnabled"); } void GS232ControllerGUI::inputConfigurationComplete() { - m_settingsKeys.append("inputControllerSettings"); - applySettings(); + applySetting("inputControllerSettings"); } GS232ControllerGUI::~GS232ControllerGUI() @@ -546,10 +539,16 @@ void GS232ControllerGUI::updateSerialPortList(const QStringList& serialPorts) ui->serialPort->blockSignals(false); } -void GS232ControllerGUI::updatePipeList(const QList& sources) +void GS232ControllerGUI::updatePipeList(const AvailableChannelOrFeatureList& sources, const QStringList& renameFrom, const QStringList& renameTo) { - QString currentText = ui->sources->currentText(); - QString newText; + // Update source settting if it has been renamed + if (renameFrom.contains(m_settings.m_source)) + { + m_settings.m_source = renameTo[renameFrom.indexOf(m_settings.m_source)]; + applySetting("source"); + } + + int prevIdx = ui->sources->currentIndex(); ui->sources->blockSignals(true); ui->sources->clear(); @@ -557,40 +556,33 @@ void GS232ControllerGUI::updatePipeList(const QListsources->addItem(source.getLongId()); } - int index = ui->sources->findText(m_settings.m_source); - ui->sources->setCurrentIndex(index); - - if (index < 0) // current source is not found + // Select current setting, if it exists + // If not, and no prior setting, make sure nothing selected, as channel/feature may be created later on + // If not found and something was previously selected, clear the setting, as probably deleted + int idx = ui->sources->findText(m_settings.m_source); + if (idx >= 0) + { + ui->sources->setCurrentIndex(idx); + } + else if (prevIdx == -1) + { + ui->sources->setCurrentIndex(-1); + } + else { m_settings.m_source = ""; + applySetting("source"); ui->targetName->setText(""); - m_settingsKeys.append("source"); - applySettings(); } - // if (currentText.isEmpty()) - // { - // // Source feature may be loaded after this, so may not have existed when - // // displaySettings was called - // if (sources.size() > 0) { - // ui->sources->setCurrentIndex(ui->sources->findText(m_settings.m_source)); - // } - // } - // else - // { - // ui->sources->setCurrentIndex(ui->sources->findText(currentText)); - // } - ui->sources->blockSignals(false); - // QString newText = ui->sources->currentText(); - - // if (currentText != newText) - // { - // m_settings.m_source = newText; - // ui->targetName->setText(""); - // applySettings(); - // } + // If no current settting, select first available + if (m_settings.m_source.isEmpty() && (ui->sources->count() > 0)) + { + ui->sources->setCurrentIndex(0); + on_sources_currentTextChanged(ui->sources->currentText()); + } } void GS232ControllerGUI::onMenuDialogCalled(const QPoint &p) @@ -620,15 +612,17 @@ void GS232ControllerGUI::onMenuDialogCalled(const QPoint &p) setTitle(m_settings.m_title); setTitleColor(m_settings.m_rgbColor); - m_settingsKeys.append("title"); - m_settingsKeys.append("rgbColor"); - m_settingsKeys.append("useReverseAPI"); - m_settingsKeys.append("reverseAPIAddress"); - m_settingsKeys.append("reverseAPIPort"); - m_settingsKeys.append("reverseAPIFeatureSetIndex"); - m_settingsKeys.append("reverseAPIFeatureIndex"); + QList settingsKeys({ + "rgbColor", + "title", + "useReverseAPI", + "reverseAPIAddress", + "reverseAPIPort", + "reverseAPIDeviceIndex", + "reverseAPIChannelIndex" + }); - applySettings(); + applySettings(settingsKeys); } resetContextMenuType(); @@ -698,15 +692,13 @@ void GS232ControllerGUI::on_protocol_currentIndexChanged(int index) { m_settings.m_protocol = (GS232ControllerSettings::Protocol)index; setProtocol(m_settings.m_protocol); - m_settingsKeys.append("protocol"); - applySettings(); + applySetting("protocol"); } void GS232ControllerGUI::on_connection_currentIndexChanged(int index) { m_settings.m_connection = (GS232ControllerSettings::Connection)index; - m_settingsKeys.append("connection"); - applySettings(); + applySetting("connection"); updateConnectionWidgets(); } @@ -714,30 +706,26 @@ void GS232ControllerGUI::on_serialPort_currentIndexChanged(int index) { (void) index; m_settings.m_serialPort = ui->serialPort->currentText(); - m_settingsKeys.append("serialPort"); - applySettings(); + applySetting("serialPort"); } void GS232ControllerGUI::on_baudRate_currentIndexChanged(int index) { (void) index; m_settings.m_baudRate = ui->baudRate->currentText().toInt(); - m_settingsKeys.append("baudRate"); - applySettings(); + applySetting("baudRate"); } void GS232ControllerGUI::on_host_editingFinished() { m_settings.m_host = ui->host->text(); - m_settingsKeys.append("host"); - applySettings(); + applySetting("host"); } void GS232ControllerGUI::on_port_valueChanged(int value) { m_settings.m_port = value; - m_settingsKeys.append("port"); - applySettings(); + applySetting("port"); } void GS232ControllerGUI::on_coord1_valueChanged(double value) @@ -764,8 +752,7 @@ void GS232ControllerGUI::on_azimuthOffset_valueChanged(double value) m_inputAzOffset = value; } m_settings.m_azimuthOffset = (float) value; - m_settingsKeys.append("azimuthOffset"); - applySettings(); + applySetting("azimuthOffset"); } void GS232ControllerGUI::on_elevationOffset_valueChanged(double value) @@ -774,58 +761,50 @@ void GS232ControllerGUI::on_elevationOffset_valueChanged(double value) m_inputElOffset = value; } m_settings.m_elevationOffset = (float) value; - m_settingsKeys.append("elevationOffset"); - applySettings(); + applySetting("elevationOffset"); } void GS232ControllerGUI::on_azimuthMin_valueChanged(int value) { m_settings.m_azimuthMin = value; - m_settingsKeys.append("azimuthMin"); - applySettings(); + applySetting("azimuthMin"); } void GS232ControllerGUI::on_azimuthMax_valueChanged(int value) { m_settings.m_azimuthMax = value; - m_settingsKeys.append("azimuthMax"); - applySettings(); + applySetting("azimuthMax"); } void GS232ControllerGUI::on_elevationMin_valueChanged(int value) { m_settings.m_elevationMin = value; - m_settingsKeys.append("elevationMin"); - applySettings(); + applySetting("elevationMin"); } void GS232ControllerGUI::on_elevationMax_valueChanged(int value) { m_settings.m_elevationMax = value; - m_settingsKeys.append("elevationMax"); - applySettings(); + applySetting("elevationMax"); } void GS232ControllerGUI::on_tolerance_valueChanged(double value) { m_settings.m_tolerance = value; - m_settingsKeys.append("tolerance"); - applySettings(); + applySetting("tolerance"); } void GS232ControllerGUI::on_precision_valueChanged(int value) { m_settings.m_precision = value; setPrecision(); - m_settingsKeys.append("precision"); - applySettings(); + applySetting("precision"); } void GS232ControllerGUI::on_coordinates_currentIndexChanged(int index) { m_settings.m_coordinates = (GS232ControllerSettings::Coordinates)index; - m_settingsKeys.append("coordinates"); - applySettings(); + applySetting("coordinates"); float coord1, coord2; azElToDisplay(m_settings.m_azimuth, m_settings.m_elevation, coord1, coord2); @@ -880,8 +859,7 @@ void GS232ControllerGUI::on_track_stateChanged(int state) ui->targetName->setText(""); } - m_settingsKeys.append("track"); - applySettings(); + applySetting("track"); } void GS232ControllerGUI::on_sources_currentTextChanged(const QString& text) @@ -889,36 +867,31 @@ void GS232ControllerGUI::on_sources_currentTextChanged(const QString& text) qDebug("GS232ControllerGUI::on_sources_currentTextChanged: %s", qPrintable(text)); m_settings.m_source = text; ui->targetName->setText(""); - m_settingsKeys.append("source"); - applySettings(); + applySetting("source"); } void GS232ControllerGUI::on_dfmTrack_clicked(bool checked) { m_settings.m_dfmTrackOn = checked; - m_settingsKeys.append("dfmTrackOn"); - applySettings(); + applySetting("dfmTrackOn"); } void GS232ControllerGUI::on_dfmLubePumps_clicked(bool checked) { m_settings.m_dfmLubePumpsOn = checked; - m_settingsKeys.append("dfmLubePumpsOn"); - applySettings(); + applySetting("dfmLubePumpsOn"); } void GS232ControllerGUI::on_dfmBrakes_clicked(bool checked) { m_settings.m_dfmBrakesOn = checked; - m_settingsKeys.append("dfmBrakesOn"); - applySettings(); + applySetting("dfmBrakesOn"); } void GS232ControllerGUI::on_dfmDrives_clicked(bool checked) { m_settings.m_dfmDrivesOn = checked; - m_settingsKeys.append("dfmDrivesOn"); - applySettings(); + applySetting("dfmDrivesOn"); } void GS232ControllerGUI::on_dfmShowStatus_clicked() @@ -983,17 +956,28 @@ void GS232ControllerGUI::updateStatus() } } -void GS232ControllerGUI::applySettings(bool force) +void GS232ControllerGUI::applySetting(const QString& settingsKey) { + applySettings({settingsKey}); +} + +void GS232ControllerGUI::applySettings(const QStringList& settingsKeys, bool force) +{ + m_settingsKeys.append(settingsKeys); if (m_doApplySettings) { GS232Controller::MsgConfigureGS232Controller* message = GS232Controller::MsgConfigureGS232Controller::create(m_settings, m_settingsKeys, force); m_gs232Controller->getInputMessageQueue()->push(message); + m_settingsKeys.clear(); } - - m_settingsKeys.clear(); } +void GS232ControllerGUI::applyAllSettings() +{ + applySettings(QStringList(), true); +} + + void GS232ControllerGUI::makeUIConnections() { QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &GS232ControllerGUI::on_startStop_toggled); diff --git a/plugins/feature/gs232controller/gs232controllergui.h b/plugins/feature/gs232controller/gs232controllergui.h index 5d5e93b6f..4a7a36347 100644 --- a/plugins/feature/gs232controller/gs232controllergui.h +++ b/plugins/feature/gs232controller/gs232controllergui.h @@ -85,12 +85,14 @@ private: virtual ~GS232ControllerGUI(); void blockApplySettings(bool block); - void applySettings(bool force = false); + void applySetting(const QString& settingsKey); + void applySettings(const QStringList& settingsKeys, bool force = false); + void applyAllSettings(); void displaySettings(); void setProtocol(GS232ControllerSettings::Protocol protocol); void setPrecision(); void updateConnectionWidgets(); - void updatePipeList(const QList& sources); + void updatePipeList(const AvailableChannelOrFeatureList& sources, const QStringList& renameFrom, const QStringList& renameTo); void updateSerialPortList(); void updateSerialPortList(const QStringList& serialPorts); bool handleMessage(const Message& message); diff --git a/plugins/feature/gs232controller/gs232controllersettings.cpp b/plugins/feature/gs232controller/gs232controllersettings.cpp index 8b3f9cfd2..cfd169815 100644 --- a/plugins/feature/gs232controller/gs232controllersettings.cpp +++ b/plugins/feature/gs232controller/gs232controllersettings.cpp @@ -2,7 +2,7 @@ // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany // // written by Christian Daniel // // Copyright (C) 2015-2017, 2019-2022 Edouard Griffiths, F4EXB // -// Copyright (C) 2020-2021, 2023 Jon Beniston, M7RCE // +// Copyright (C) 2020-2021, 2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -26,14 +26,6 @@ #include "gs232controllersettings.h" #include "inputcontrollersettings.h" -const QStringList GS232ControllerSettings::m_pipeTypes = { - QStringLiteral("ADSBDemod"), - QStringLiteral("Map"), - QStringLiteral("SkyMap"), - QStringLiteral("StarTracker"), - QStringLiteral("SatelliteTracker") -}; - const QStringList GS232ControllerSettings::m_pipeURIs = { QStringLiteral("sdrangel.channel.adsbdemod"), QStringLiteral("sdrangel.feature.map"), diff --git a/plugins/feature/gs232controller/gs232controllersettings.h b/plugins/feature/gs232controller/gs232controllersettings.h index 57cddff25..9d6e3b81b 100644 --- a/plugins/feature/gs232controller/gs232controllersettings.h +++ b/plugins/feature/gs232controller/gs232controllersettings.h @@ -2,7 +2,7 @@ // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany // // written by Christian Daniel // // Copyright (C) 2015-2022 Edouard Griffiths, F4EXB // -// Copyright (C) 2020-2021, 2023 Jon Beniston, M7RCE // +// Copyright (C) 2020-2021, 2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -81,7 +81,6 @@ struct GS232ControllerSettings void applySettings(const QStringList& settingsKeys, const GS232ControllerSettings& settings); QString getDebugString(const QStringList& settingsKeys, bool force=false) const; - static const QStringList m_pipeTypes; static const QStringList m_pipeURIs; }; diff --git a/plugins/feature/gs232controller/readme.md b/plugins/feature/gs232controller/readme.md index f5106599d..e066512f8 100644 --- a/plugins/feature/gs232controller/readme.md +++ b/plugins/feature/gs232controller/readme.md @@ -185,8 +185,8 @@ The controller uses the 'P' and 'p' commands to set and get azimuth and elevatio Full details of the API can be found in the Swagger documentation. Here is a quick example of how to set the azimuth and elevation from the command line: - curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "GS232Controller", "GS232ControllerSettings": { "azimuth": 180, "elevation": 45 }}' + curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "GS232Controller", "GS232ControllerSettings": { "azimuth": 180, "elevation": 45 }}' To start sending commands to the rotator: - curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/run" + curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/feature/0/run" diff --git a/plugins/feature/pertester/readme.md b/plugins/feature/pertester/readme.md index b6e4ad87b..73db96bca 100644 --- a/plugins/feature/pertester/readme.md +++ b/plugins/feature/pertester/readme.md @@ -97,8 +97,8 @@ The statistics fields display the statistics for the current test: Full details of the API can be found in the Swagger documentation. Here is a quick example of how to set the azimuth and elevation from the command line: - curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "PERTester", "PERTesterSettings": { "packetCount": 100 }}' + curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "PERTester", "PERTesterSettings": { "packetCount": 100 }}' To start sending the test: - curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/run" + curl -X POST "http://127.0.0.1:8091/sdrangel/featureset/feature/0/run" diff --git a/plugins/feature/radiosonde/radiosonde.cpp b/plugins/feature/radiosonde/radiosonde.cpp index 8dc985677..0fcafa60b 100644 --- a/plugins/feature/radiosonde/radiosonde.cpp +++ b/plugins/feature/radiosonde/radiosonde.cpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2021-2022 Edouard Griffiths, F4EXB // -// Copyright (C) 2021-2022 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -41,7 +41,8 @@ const char* const Radiosonde::m_featureIdURI = "sdrangel.feature.radiosonde"; const char* const Radiosonde::m_featureId = "Radiosonde"; Radiosonde::Radiosonde(WebAPIAdapterInterface *webAPIAdapterInterface) : - Feature(m_featureIdURI, webAPIAdapterInterface) + Feature(m_featureIdURI, webAPIAdapterInterface), + m_availableChannelHandler({"sdrangel.channel.radiosondedemod"}, QStringList{"radiosonde"}) { qDebug("Radiosonde::Radiosonde: webAPIAdapterInterface: %p", webAPIAdapterInterface); setObjectName(m_featureId); @@ -54,22 +55,22 @@ Radiosonde::Radiosonde(WebAPIAdapterInterface *webAPIAdapterInterface) : this, &Radiosonde::networkManagerFinished ); - scanAvailableChannels(); + QObject::connect( - MainCore::instance(), - &MainCore::channelAdded, + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &Radiosonde::handleChannelAdded - ); + &Radiosonde::handleChannelMessageQueue); + m_availableChannelHandler.scanAvailableChannelsAndFeatures(); } Radiosonde::~Radiosonde() { QObject::disconnect( - MainCore::instance(), - &MainCore::channelAdded, + &m_availableChannelHandler, + &AvailableChannelOrFeatureHandler::messageEnqueued, this, - &Radiosonde::handleChannelAdded + &Radiosonde::handleChannelMessageQueue ); QObject::disconnect( m_networkManager, @@ -362,90 +363,6 @@ void Radiosonde::networkManagerFinished(QNetworkReply *reply) reply->deleteLater(); } -void Radiosonde::scanAvailableChannels() -{ - MainCore *mainCore = MainCore::instance(); - MessagePipes& messagePipes = mainCore->getMessagePipes(); - std::vector& 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(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& 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(pipe->m_element); - QObject::connect( - messageQueue, - &MessageQueue::messageEnqueued, - this, - [=](){ this->handleChannelMessageQueue(messageQueue); }, - Qt::QueuedConnection - ); - QObject::connect( - pipe, - &ObjectPipe::toBeDeleted, - this, - &Radiosonde::handleMessagePipeToBeDeleted - ); - m_availableChannels.insert(channel); - } - } -} - -void Radiosonde::handleMessagePipeToBeDeleted(int reason, QObject* object) -{ - if ((reason == 0) && m_availableChannels.contains((ChannelAPI*) object)) // producer (channel) - { - qDebug("Radiosonde::handleMessagePipeToBeDeleted: removing channel at (%p)", object); - m_availableChannels.remove((ChannelAPI*) object); - } -} - void Radiosonde::handleChannelMessageQueue(MessageQueue* messageQueue) { Message* message; diff --git a/plugins/feature/radiosonde/radiosonde.h b/plugins/feature/radiosonde/radiosonde.h index af3f1d676..a5a99f602 100644 --- a/plugins/feature/radiosonde/radiosonde.h +++ b/plugins/feature/radiosonde/radiosonde.h @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020, 2022 Edouard Griffiths, F4EXB // // Copyright (C) 2020 Kacper Michajłow // -// Copyright (C) 2021-2022 Jon Beniston, M7RCE // +// Copyright (C) 2021-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -25,6 +25,7 @@ #include "feature/feature.h" #include "util/message.h" +#include "availablechannelorfeaturehandler.h" #include "radiosondesettings.h" @@ -101,7 +102,8 @@ public: private: RadiosondeSettings m_settings; - QSet m_availableChannels; + AvailableChannelOrFeatureHandler m_availableChannelHandler; + AvailableChannelOrFeatureList m_availableChannels; QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; @@ -110,12 +112,9 @@ private: void stop(); void applySettings(const RadiosondeSettings& settings, const QList& settingsKeys, bool force = false); void webapiReverseSendSettings(const QList& featureSettingsKeys, const RadiosondeSettings& settings, bool force); - void scanAvailableChannels(); private slots: void networkManagerFinished(QNetworkReply *reply); - void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel); - void handleMessagePipeToBeDeleted(int reason, QObject* object); void handleChannelMessageQueue(MessageQueue* messageQueue); }; diff --git a/plugins/feature/satellitetracker/readme.md b/plugins/feature/satellitetracker/readme.md index 0348f697c..6dc1b5cc7 100644 --- a/plugins/feature/satellitetracker/readme.md +++ b/plugins/feature/satellitetracker/readme.md @@ -216,12 +216,12 @@ Icons are by Freepik from Flaticon https://www.flaticon.com/ Full details of the API can be found in the Swagger documentation. Here is a quick example of how to set the satellites to track: - curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "satellites": [ "NOAA 15", "NOAA 19" ] }}' + curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "satellites": [ "NOAA 15", "NOAA 19" ] }}' And how to set the target: - curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "target": "NOAA 15" }}' + curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "target": "NOAA 15" }}' Or, to set the device settings: - curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/0/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "deviceSettings": [ { "satellite": "ISS", "deviceSettings": [ { "deviceSet": "R0", "doppler": [0], "frequency": 0, "presetDescription": Sat", "presetFrequency": 145.825, "presetGroup": "ISS Digi", "startOnAOS": 1, "startStopFileSinks": 1, "stopOnLOS": 1}] } ] }}' + curl -X PATCH "http://127.0.0.1:8091/sdrangel/featureset/feature/0/settings" -d '{"featureType": "SatelliteTracker", "SatelliteTrackerSettings": { "deviceSettings": [ { "satellite": "ISS", "deviceSettings": [ { "deviceSet": "R0", "doppler": [0], "frequency": 0, "presetDescription": Sat", "presetFrequency": 145.825, "presetGroup": "ISS Digi", "startOnAOS": 1, "startStopFileSinks": 1, "stopOnLOS": 1}] } ] }}' diff --git a/plugins/feature/skymap/html/esasky.html b/plugins/feature/skymap/html/esasky.html index 8362ed7d1..2161e4818 100644 --- a/plugins/feature/skymap/html/esasky.html +++ b/plugins/feature/skymap/html/esasky.html @@ -9,8 +9,8 @@