mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00:26 -04:00 
			
		
		
		
	Merge pull request #1911 from srcejon/freq_scanner
Map: Support multiple frequencies and specify which device to tune
This commit is contained in:
		
						commit
						364dfc1fc5
					
				
							
								
								
									
										6
									
								
								.github/workflows/sdrangel.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/sdrangel.yml
									
									
									
									
										vendored
									
									
								
							| @ -111,9 +111,9 @@ jobs: | |||||||
|       - name: Install brew uhd package |       - name: Install brew uhd package | ||||||
|         run: | |         run: | | ||||||
|           rm -f /usr/local/bin/2to3* |           rm -f /usr/local/bin/2to3* | ||||||
|           rm -f /usr/local/bin/idle3 |           rm -f /usr/local/bin/idle3* | ||||||
|           rm -f /usr/local/bin/pydoc3 |           rm -f /usr/local/bin/pydoc3* | ||||||
|           rm -f /usr/local/bin/python3 |           rm -f /usr/local/bin/python3* | ||||||
|           rm -f /usr/local/bin/python3-config |           rm -f /usr/local/bin/python3-config | ||||||
|           brew install uhd |           brew install uhd | ||||||
|       - name: Install brew opencv package |       - name: Install brew opencv package | ||||||
|  | |||||||
| @ -577,12 +577,7 @@ void AircraftModel::findOnMap(int index) | |||||||
| // Get list of frequeny scanners to use in menu
 | // Get list of frequeny scanners to use in menu
 | ||||||
| QStringList AirportModel::getFreqScanners() const | QStringList AirportModel::getFreqScanners() const | ||||||
| { | { | ||||||
|     QStringList list; |     return MainCore::instance()->getChannelIds("sdrangel.channel.freqscanner"); | ||||||
|     std::vector<ChannelAPI*> channels = MainCore::instance()->getChannels("sdrangel.channel.freqscanner"); |  | ||||||
|     for (const auto channel : channels) { |  | ||||||
|         list.append(QString("R%1:%2").arg(channel->getDeviceSetIndex()).arg(channel->getIndexInDeviceSet())); |  | ||||||
|     } |  | ||||||
|     return list; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Send airport frequencies to frequency scanner with given id (Rn:n)
 | // Send airport frequencies to frequency scanner with given id (Rn:n)
 | ||||||
| @ -592,14 +587,10 @@ void AirportModel::sendToFreqScanner(int index, const QString& id) | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     const AirportInformation *airport = m_airports[index]; |     const AirportInformation *airport = m_airports[index]; | ||||||
|  |     unsigned int deviceSet, channelIndex; | ||||||
| 
 | 
 | ||||||
|     const QRegularExpression re("R([0-9]+):([0-9]+)"); |     if (MainCore::getDeviceAndChannelIndexFromId(id, deviceSet, channelIndex)) | ||||||
|     QRegularExpressionMatch match = re.match(id); |  | ||||||
|     if (match.hasMatch()) |  | ||||||
|     { |     { | ||||||
|         int deviceSet = match.capturedTexts()[1].toInt(); |  | ||||||
|         int channelIndex = match.capturedTexts()[2].toInt(); |  | ||||||
| 
 |  | ||||||
|         QJsonArray array; |         QJsonArray array; | ||||||
|         for (const auto airportFrequency : airport->m_frequencies) |         for (const auto airportFrequency : airport->m_frequencies) | ||||||
|         { |         { | ||||||
| @ -867,12 +858,10 @@ bool NavAidModel::setData(const QModelIndex &index, const QVariant& value, int r | |||||||
| // Set selected AM Demod to the given frequency (used to tune to ATC selected from airports on map)
 | // Set selected AM Demod to the given frequency (used to tune to ATC selected from airports on map)
 | ||||||
| bool ADSBDemodGUI::setFrequency(qint64 targetFrequencyHz) | bool ADSBDemodGUI::setFrequency(qint64 targetFrequencyHz) | ||||||
| { | { | ||||||
|     const QRegularExpression re("R([0-9]+):([0-9]+)"); |     unsigned int deviceSet, channelIndex; | ||||||
|     QRegularExpressionMatch match = re.match(m_settings.m_amDemod); | 
 | ||||||
|     if (match.hasMatch()) |     if (MainCore::getDeviceAndChannelIndexFromId(m_settings.m_amDemod, deviceSet, channelIndex)) | ||||||
|     { |     { | ||||||
|         int deviceSet = match.capturedTexts()[1].toInt(); |  | ||||||
|         int channelIndex = match.capturedTexts()[2].toInt(); |  | ||||||
|         const int halfChannelBW = 20000/2; |         const int halfChannelBW = 20000/2; | ||||||
|         int dcOffset = halfChannelBW; |         int dcOffset = halfChannelBW; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ | |||||||
| #include <QNetworkReply> | #include <QNetworkReply> | ||||||
| #include <QBuffer> | #include <QBuffer> | ||||||
| #include <QThread> | #include <QThread> | ||||||
| #include <QRegExp> |  | ||||||
| 
 | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <complex.h> | #include <complex.h> | ||||||
| @ -67,8 +66,8 @@ FreqScanner::FreqScanner(DeviceAPI *deviceAPI) : | |||||||
|         m_basebandSink(nullptr), |         m_basebandSink(nullptr), | ||||||
|         m_running(false), |         m_running(false), | ||||||
|         m_basebandSampleRate(0), |         m_basebandSampleRate(0), | ||||||
|         m_scanDeviceSetIndex(-1), |         m_scanDeviceSetIndex(0), | ||||||
|         m_scanChannelIndex(-1), |         m_scanChannelIndex(0), | ||||||
|         m_state(IDLE), |         m_state(IDLE), | ||||||
|         m_timeoutTimer(this) |         m_timeoutTimer(this) | ||||||
| { | { | ||||||
| @ -670,28 +669,19 @@ void FreqScanner::muteAll(const FreqScannerSettings& settings) | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const QRegExp re("R([0-9]+):([0-9]+)"); |  | ||||||
|     for (const auto& channel : channels) |     for (const auto& channel : channels) | ||||||
|     { |     { | ||||||
|         if (re.indexIn(channel) >= 0) |         unsigned int deviceSetIndex, channelIndex; | ||||||
|         { | 
 | ||||||
|             int deviceSetIndex = re.capturedTexts()[1].toInt(); |         if (MainCore::getDeviceAndChannelIndexFromId(channel, deviceSetIndex, channelIndex)) { | ||||||
|             int scanChannelIndex = re.capturedTexts()[2].toInt(); |             ChannelWebAPIUtils::setAudioMute(deviceSetIndex, channelIndex, true); | ||||||
|             ChannelWebAPIUtils::setAudioMute(deviceSetIndex, scanChannelIndex, true); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void FreqScanner::applyChannelSetting(const QString& channel) | void FreqScanner::applyChannelSetting(const QString& channel) | ||||||
| { | { | ||||||
|     const QRegExp re("R([0-9]+):([0-9]+)"); |     if (!MainCore::getDeviceAndChannelIndexFromId(channel, m_scanDeviceSetIndex, m_scanChannelIndex)) { | ||||||
|     if (re.indexIn(channel) >= 0) |  | ||||||
|     { |  | ||||||
|         m_scanDeviceSetIndex = re.capturedTexts()[1].toInt(); |  | ||||||
|         m_scanChannelIndex = re.capturedTexts()[2].toInt(); |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         qDebug() << "FreqScanner::applySettings: Failed to parse channel" << channel; |         qDebug() << "FreqScanner::applySettings: Failed to parse channel" << channel; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -370,8 +370,8 @@ private: | |||||||
| 
 | 
 | ||||||
|     QHash<ChannelAPI*, FreqScannerSettings::AvailableChannel> m_availableChannels; |     QHash<ChannelAPI*, FreqScannerSettings::AvailableChannel> m_availableChannels; | ||||||
| 
 | 
 | ||||||
|     int m_scanDeviceSetIndex; |     unsigned int m_scanDeviceSetIndex; | ||||||
|     int m_scanChannelIndex; |     unsigned int m_scanChannelIndex; | ||||||
|     qint64 m_activeFrequency; |     qint64 m_activeFrequency; | ||||||
|     QDateTime m_minFFTStartTime; |     QDateTime m_minFFTStartTime; | ||||||
|     int m_scannerSampleRate; |     int m_scannerSampleRate; | ||||||
|  | |||||||
| @ -21,7 +21,6 @@ | |||||||
| #include <QMenu> | #include <QMenu> | ||||||
| #include <QTableWidget> | #include <QTableWidget> | ||||||
| #include <QTableWidgetItem> | #include <QTableWidgetItem> | ||||||
| #include <QRegExp> |  | ||||||
| #include <QComboBox> | #include <QComboBox> | ||||||
| 
 | 
 | ||||||
| #include "device/deviceset.h" | #include "device/deviceset.h" | ||||||
| @ -41,6 +40,7 @@ | |||||||
| #include "gui/int64delegate.h" | #include "gui/int64delegate.h" | ||||||
| #include "gui/glspectrum.h" | #include "gui/glspectrum.h" | ||||||
| #include "channel/channelwebapiutils.h" | #include "channel/channelwebapiutils.h" | ||||||
|  | #include "maincore.h" | ||||||
| 
 | 
 | ||||||
| #include "freqscannergui.h" | #include "freqscannergui.h" | ||||||
| #include "freqscanneraddrangedialog.h" | #include "freqscanneraddrangedialog.h" | ||||||
| @ -935,15 +935,13 @@ void FreqScannerGUI::table_customContextMenuRequested(QPoint pos) | |||||||
|         qint64 frequency = ui->table->item(row, COL_FREQUENCY)->text().toLongLong(); |         qint64 frequency = ui->table->item(row, COL_FREQUENCY)->text().toLongLong(); | ||||||
|         FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(frequency); |         FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(frequency); | ||||||
|         QString channel = m_settings.getChannel(frequencySettings); |         QString channel = m_settings.getChannel(frequencySettings); | ||||||
|         const QRegExp re("R([0-9]+):([0-9]+)"); |         unsigned int scanDeviceSetIndex, scanChannelIndex; | ||||||
|         if (re.indexIn(channel) >= 0) |  | ||||||
|         { |  | ||||||
|             int scanDeviceSetIndex = re.capturedTexts()[1].toInt(); |  | ||||||
|             int scanChannelIndex = re.capturedTexts()[2].toInt(); |  | ||||||
| 
 | 
 | ||||||
|  |         if (MainCore::getDeviceAndChannelIndexFromId(channel, scanDeviceSetIndex, scanChannelIndex)) | ||||||
|  |         { | ||||||
|             ButtonSwitch *startStop = ui->startStop; |             ButtonSwitch *startStop = ui->startStop; | ||||||
| 
 | 
 | ||||||
|             QAction* findChannelMapAction = new QAction(QString("Tune R%1:%2 to %3").arg(scanDeviceSetIndex).arg(scanChannelIndex).arg(frequency), tableContextMenu); |             QAction* findChannelMapAction = new QAction(QString("Tune %1 to %2").arg(channel).arg(frequency), tableContextMenu); | ||||||
|             connect(findChannelMapAction, &QAction::triggered, this, [this, scanDeviceSetIndex, scanChannelIndex, frequency, startStop]()->void { |             connect(findChannelMapAction, &QAction::triggered, this, [this, scanDeviceSetIndex, scanChannelIndex, frequency, startStop]()->void { | ||||||
| 
 | 
 | ||||||
|                 // Stop scanning
 |                 // Stop scanning
 | ||||||
|  | |||||||
| @ -24,7 +24,6 @@ | |||||||
| #include <QNetworkReply> | #include <QNetworkReply> | ||||||
| #include <QBuffer> | #include <QBuffer> | ||||||
| #include <QThread> | #include <QThread> | ||||||
| #include <QRegExp> |  | ||||||
| #include <QProcess> | #include <QProcess> | ||||||
| 
 | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| @ -479,12 +478,8 @@ void RadioAstronomy::sweepStart() | |||||||
|     m_sweep1 = m_sweep1Start; |     m_sweep1 = m_sweep1Start; | ||||||
|     m_sweep2 = m_settings.m_sweep2Start; |     m_sweep2 = m_settings.m_sweep2Start; | ||||||
| 
 | 
 | ||||||
|     const QRegExp re("F([0-9]+):([0-9]+)"); |     if (MainCore::getFeatureIndexFromId(m_settings.m_starTracker, m_starTrackerFeatureSetIndex, m_starTrackerFeatureIndex)) | ||||||
|     if (re.indexIn(m_settings.m_starTracker) >= 0) |  | ||||||
|     { |     { | ||||||
|         m_starTrackerFeatureSetIndex = re.capturedTexts()[1].toInt(); |  | ||||||
|         m_starTrackerFeatureIndex = re.capturedTexts()[2].toInt(); |  | ||||||
| 
 |  | ||||||
|         if (m_settings.m_sweepType == RadioAstronomySettings::SWP_AZEL) { |         if (m_settings.m_sweepType == RadioAstronomySettings::SWP_AZEL) { | ||||||
|             ChannelWebAPIUtils::patchFeatureSetting(m_starTrackerFeatureSetIndex, m_starTrackerFeatureIndex, "target", "Custom Az/El"); |             ChannelWebAPIUtils::patchFeatureSetting(m_starTrackerFeatureSetIndex, m_starTrackerFeatureIndex, "target", "Custom Az/El"); | ||||||
|         } else if (m_settings.m_sweepType == RadioAstronomySettings::SWP_LB) { |         } else if (m_settings.m_sweepType == RadioAstronomySettings::SWP_LB) { | ||||||
| @ -499,11 +494,8 @@ void RadioAstronomy::sweepStart() | |||||||
|             sweep2(); |             sweep2(); | ||||||
|             callOnStartTime(&RadioAstronomy::sweep1); |             callOnStartTime(&RadioAstronomy::sweep1); | ||||||
|         } |         } | ||||||
|         else if (re.indexIn(m_settings.m_rotator) >= 0) |         else if (MainCore::getFeatureIndexFromId(m_settings.m_rotator, m_rotatorFeatureSetIndex, m_rotatorFeatureIndex)) | ||||||
|         { |         { | ||||||
|             m_rotatorFeatureSetIndex = re.capturedTexts()[1].toInt(); |  | ||||||
|             m_rotatorFeatureIndex = re.capturedTexts()[2].toInt(); |  | ||||||
| 
 |  | ||||||
|             sweep2(); |             sweep2(); | ||||||
|             callOnStartTime(&RadioAstronomy::sweep1); |             callOnStartTime(&RadioAstronomy::sweep1); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -454,10 +454,10 @@ private: | |||||||
|     QNetworkAccessManager *m_networkManager; |     QNetworkAccessManager *m_networkManager; | ||||||
|     QNetworkRequest m_networkRequest; |     QNetworkRequest m_networkRequest; | ||||||
| 
 | 
 | ||||||
|     int m_starTrackerFeatureSetIndex; |     unsigned int m_starTrackerFeatureSetIndex; | ||||||
|     int m_starTrackerFeatureIndex; |     unsigned int m_starTrackerFeatureIndex; | ||||||
|     int m_rotatorFeatureSetIndex; |     unsigned int m_rotatorFeatureSetIndex; | ||||||
|     int m_rotatorFeatureIndex; |     unsigned int m_rotatorFeatureIndex; | ||||||
| 
 | 
 | ||||||
|     float m_sweep1;     // Current sweep position
 |     float m_sweep1;     // Current sweep position
 | ||||||
|     float m_sweep2; |     float m_sweep2; | ||||||
|  | |||||||
| @ -2744,12 +2744,10 @@ void RadioAstronomyGUI::on_rotator_currentTextChanged(const QString& text) | |||||||
| void RadioAstronomyGUI::setColumnPrecisionFromRotator() | void RadioAstronomyGUI::setColumnPrecisionFromRotator() | ||||||
| { | { | ||||||
|     // Match rotator precision
 |     // Match rotator precision
 | ||||||
|     const QRegExp re("F([0-9]+):([0-9]+)"); |     unsigned int featureSetIndex, featureIndex; | ||||||
|     if (re.indexIn(m_settings.m_rotator) >= 0) |  | ||||||
|     { |  | ||||||
|         int featureSetIndex = re.capturedTexts()[1].toInt(); |  | ||||||
|         int featureIndex = re.capturedTexts()[2].toInt(); |  | ||||||
| 
 | 
 | ||||||
|  |     if (MainCore::getFeatureIndexFromId(m_settings.m_rotator, featureSetIndex, featureIndex)) | ||||||
|  |     { | ||||||
|         int precision = 0; |         int precision = 0; | ||||||
|         if (ChannelWebAPIUtils::getFeatureSetting(featureSetIndex, featureIndex, "precision", precision)) |         if (ChannelWebAPIUtils::getFeatureSetting(featureSetIndex, featureIndex, "precision", precision)) | ||||||
|         { |         { | ||||||
| @ -4687,12 +4685,10 @@ void RadioAstronomyGUI::addFFT(FFTMeasurement *fft, bool skipCalcs) | |||||||
| 
 | 
 | ||||||
| void RadioAstronomyGUI::getRotatorData(FFTMeasurement *fft) | void RadioAstronomyGUI::getRotatorData(FFTMeasurement *fft) | ||||||
| { | { | ||||||
|     const QRegExp re("F([0-9]+):([0-9]+)"); |     unsigned int rotatorFeatureSetIndex, rotatorFeatureIndex; | ||||||
|     if (re.indexIn(m_settings.m_rotator) >= 0) |  | ||||||
|     { |  | ||||||
|         int rotatorFeatureSetIndex = re.capturedTexts()[1].toInt(); |  | ||||||
|         int rotatorFeatureIndex = re.capturedTexts()[2].toInt(); |  | ||||||
| 
 | 
 | ||||||
|  |     if (MainCore::getFeatureIndexFromId(m_settings.m_rotator, rotatorFeatureSetIndex, rotatorFeatureIndex)) | ||||||
|  |     { | ||||||
|         SWGSDRangel::SWGFeatureReport featureReport; |         SWGSDRangel::SWGFeatureReport featureReport; | ||||||
|         double value; |         double value; | ||||||
|         qDebug() << m_settings.m_rotator << rotatorFeatureSetIndex << rotatorFeatureIndex; |         qDebug() << m_settings.m_rotator << rotatorFeatureSetIndex << rotatorFeatureIndex; | ||||||
|  | |||||||
| @ -269,12 +269,24 @@ Item { | |||||||
|                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) |                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) | ||||||
|                                     } |                                     } | ||||||
|                                 } else if (mouse.button === Qt.RightButton) { |                                 } else if (mouse.button === Qt.RightButton) { | ||||||
|                                     if (frequency > 0) { |                                     menuItems.clear() | ||||||
|                                         freqMenuItem.text = "Set frequency to " + frequencyString |                                     menus.clear() | ||||||
|                                         freqMenuItem.enabled = true |                                     if (frequencies.length > 0) { | ||||||
|                                     } else { |                                         var deviceSets = mapModel.getDeviceSets() | ||||||
|                                         freqMenuItem.text = "No frequency available" |                                         for (var i = 0; i < deviceSets.length; i++) { | ||||||
|                                         freqMenuItem.enabled = false |                                             menus.append({ | ||||||
|  |                                                 title: "Set " + deviceSets[i] + " to...", | ||||||
|  |                                                 deviceSet: i | ||||||
|  |                                             }) | ||||||
|  |                                             for (var j = 0; j < frequencies.length; j++) { | ||||||
|  |                                                 menuItems.append({ | ||||||
|  |                                                     text: frequencyStrings[j], | ||||||
|  |                                                     frequency: frequencies[j], | ||||||
|  |                                                     deviceSet: deviceSets[i], | ||||||
|  |                                                     menuIndex: i | ||||||
|  |                                                 }) | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|                                     } |                                     } | ||||||
|                                     var c = mapPtr.toCoordinate(Qt.point(mouse.x, mouse.y)) |                                     var c = mapPtr.toCoordinate(Qt.point(mouse.x, mouse.y)) | ||||||
|                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) |                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) | ||||||
| @ -308,29 +320,42 @@ Item { | |||||||
|                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) |                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) | ||||||
|                                     } |                                     } | ||||||
|                                 } else if (mouse.button === Qt.RightButton) { |                                 } else if (mouse.button === Qt.RightButton) { | ||||||
|                                     if (frequency > 0) { |                                     menuItems.clear() | ||||||
|                                         freqMenuItem.text = "Set frequency to " + frequencyString |                                     menus.clear() | ||||||
|                                         freqMenuItem.enabled = true |                                     if (frequencies.length > 0) { | ||||||
|                                     } else { |                                         var deviceSets = mapModel.getDeviceSets() | ||||||
|                                         freqMenuItem.text = "No frequency available" |                                         for (var i = 0; i < deviceSets.length; i++) { | ||||||
|                                         freqMenuItem.enabled = false |                                             menus.append({ | ||||||
|  |                                                 title: "Set " + deviceSets[i] + " to...", | ||||||
|  |                                                 deviceSet: i | ||||||
|  |                                             }) | ||||||
|  |                                             for (var j = 0; j < frequencies.length; j++) { | ||||||
|  |                                                 menuItems.append({ | ||||||
|  |                                                     text: frequencyStrings[j], | ||||||
|  |                                                     frequency: frequencies[j], | ||||||
|  |                                                     deviceSet: deviceSets[i], | ||||||
|  |                                                     menuIndex: i | ||||||
|  |                                                 }) | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|                                     } |                                     } | ||||||
|                                     var c = mapPtr.toCoordinate(Qt.point(mouse.x, mouse.y)) |                                     var c = mapPtr.toCoordinate(Qt.point(mouse.x, mouse.y)) | ||||||
|                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) |                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) | ||||||
|                                     contextMenu.popup() |                                     contextMenu.popup() | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|  |                             ListModel { | ||||||
|  |                                 id: menus | ||||||
|  |                             } | ||||||
|  |                             ListModel { | ||||||
|  |                                 id: menuItems | ||||||
|  |                             } | ||||||
|                             Menu { |                             Menu { | ||||||
|                                 id: contextMenu |                                 id: contextMenu | ||||||
|                                 MenuItem { |                                 MenuItem { | ||||||
|                                     text: "Set as target" |                                     text: "Set as target" | ||||||
|                                     onTriggered: target = true |                                     onTriggered: target = true | ||||||
|                                 } |                                 } | ||||||
|                                 MenuItem { |  | ||||||
|                                     id: freqMenuItem |  | ||||||
|                                     text: "Not set" |  | ||||||
|                                     onTriggered: mapModel.setFrequency(frequency) |  | ||||||
|                                 } |  | ||||||
|                                 MenuItem { |                                 MenuItem { | ||||||
|                                     text: "Move to front" |                                     text: "Move to front" | ||||||
|                                     onTriggered: mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) |                                     onTriggered: mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) | ||||||
| @ -347,6 +372,38 @@ Item { | |||||||
|                                     id: coordsMenuItem |                                     id: coordsMenuItem | ||||||
|                                     text: "" |                                     text: "" | ||||||
|                                 } |                                 } | ||||||
|  |                                 Instantiator { | ||||||
|  |                                     model: menus | ||||||
|  |                                     delegate: Menu { | ||||||
|  |                                         //cascade: true | ||||||
|  |                                         id: contextSubMenu | ||||||
|  |                                         title: model.title | ||||||
|  |                                     } | ||||||
|  |                                     onObjectAdded: function(index, object) { | ||||||
|  |                                         contextMenu.insertMenu(index, object) | ||||||
|  |                                     } | ||||||
|  |                                     onObjectRemoved: function(index, object) { | ||||||
|  |                                         contextMenu.removeMenu(object) | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                                 Instantiator { | ||||||
|  |                                     model: menuItems | ||||||
|  |                                     delegate: MenuItem { | ||||||
|  |                                         text: model.text | ||||||
|  |                                         onTriggered: mapModel.setFrequency(model.frequency, model.deviceSet) | ||||||
|  |                                     } | ||||||
|  |                                     onObjectAdded: function(index, object) { | ||||||
|  |                                         // index is index in to menuItems model | ||||||
|  |                                         // object is the MenuItem | ||||||
|  |                                         var menuItem = menuItems.get(index) | ||||||
|  |                                         var menu = menus.get(menuItem.menuIndex) | ||||||
|  |                                         contextMenu.menuAt(menuItem.menuIndex).insertItem(index, object) | ||||||
|  |                                     } | ||||||
|  |                                     onObjectRemoved: function(index, object) { | ||||||
|  |                                         // Can't use menuItems.get(index) here, as already removed from model | ||||||
|  |                                         object.menu.removeItem(object) | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -282,12 +282,24 @@ Item { | |||||||
|                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) |                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) | ||||||
|                                     } |                                     } | ||||||
|                                 } else if (mouse.button === Qt.RightButton) { |                                 } else if (mouse.button === Qt.RightButton) { | ||||||
|                                     if (frequency > 0) { |                                     menuItems.clear() | ||||||
|                                         freqMenuItem.text = "Set frequency to " + frequencyString |                                     menus.clear() | ||||||
|                                         freqMenuItem.enabled = true |                                     if (frequencies.length > 0) { | ||||||
|                                     } else { |                                         var deviceSets = mapModel.getDeviceSets() | ||||||
|                                         freqMenuItem.text = "No frequency available" |                                         for (var i = 0; i < deviceSets.length; i++) { | ||||||
|                                         freqMenuItem.enabled = false |                                             menus.append({ | ||||||
|  |                                                 title: "Set " + deviceSets[i] + " to...", | ||||||
|  |                                                 deviceSet: i | ||||||
|  |                                             }) | ||||||
|  |                                             for (var j = 0; j < frequencies.length; j++) { | ||||||
|  |                                                 menuItems.append({ | ||||||
|  |                                                     text: frequencyStrings[j], | ||||||
|  |                                                     frequency: frequencies[j], | ||||||
|  |                                                     deviceSet: deviceSets[i], | ||||||
|  |                                                     menuIndex: i | ||||||
|  |                                                 }) | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|                                     } |                                     } | ||||||
|                                     var c = mapPtr.map.toCoordinate(Qt.point(mouse.x, mouse.y)) |                                     var c = mapPtr.map.toCoordinate(Qt.point(mouse.x, mouse.y)) | ||||||
|                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) |                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) | ||||||
| @ -321,29 +333,42 @@ Item { | |||||||
|                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) |                                         mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) | ||||||
|                                     } |                                     } | ||||||
|                                 } else if (mouse.button === Qt.RightButton) { |                                 } else if (mouse.button === Qt.RightButton) { | ||||||
|                                     if (frequency > 0) { |                                     menuItems.clear() | ||||||
|                                         freqMenuItem.text = "Set frequency to " + frequencyString |                                     menus.clear() | ||||||
|                                         freqMenuItem.enabled = true |                                     if (frequencies.length > 0) { | ||||||
|                                     } else { |                                         var deviceSets = mapModel.getDeviceSets() | ||||||
|                                         freqMenuItem.text = "No frequency available" |                                         for (var i = 0; i < deviceSets.length; i++) { | ||||||
|                                         freqMenuItem.enabled = false |                                             menus.append({ | ||||||
|  |                                                 title: "Set " + deviceSets[i] + " to...", | ||||||
|  |                                                 deviceSet: i | ||||||
|  |                                             }) | ||||||
|  |                                             for (var j = 0; j < frequencies.length; j++) { | ||||||
|  |                                                 menuItems.append({ | ||||||
|  |                                                     text: frequencyStrings[j], | ||||||
|  |                                                     frequency: frequencies[j], | ||||||
|  |                                                     deviceSet: deviceSets[i], | ||||||
|  |                                                     menuIndex: i | ||||||
|  |                                                 }) | ||||||
|  |                                             } | ||||||
|  |                                         } | ||||||
|                                     } |                                     } | ||||||
|                                     var c = mapPtr.map.toCoordinate(Qt.point(mouse.x, mouse.y)) |                                     var c = mapPtr.map.toCoordinate(Qt.point(mouse.x, mouse.y)) | ||||||
|                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) |                                     coordsMenuItem.text = "Coords: " + c.latitude.toFixed(6) + ", " + c.longitude.toFixed(6) | ||||||
|                                     contextMenu.popup() |                                     contextMenu.popup() | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|  |                             ListModel { | ||||||
|  |                                 id: menus | ||||||
|  |                             } | ||||||
|  |                             ListModel { | ||||||
|  |                                 id: menuItems | ||||||
|  |                             } | ||||||
|                             Menu { |                             Menu { | ||||||
|                                 id: contextMenu |                                 id: contextMenu | ||||||
|                                 MenuItem { |                                 MenuItem { | ||||||
|                                     text: "Set as target" |                                     text: "Set as target" | ||||||
|                                     onTriggered: target = true |                                     onTriggered: target = true | ||||||
|                                 } |                                 } | ||||||
|                                 MenuItem { |  | ||||||
|                                     id: freqMenuItem |  | ||||||
|                                     text: "Not set" |  | ||||||
|                                     onTriggered: mapModel.setFrequency(frequency) |  | ||||||
|                                 } |  | ||||||
|                                 MenuItem { |                                 MenuItem { | ||||||
|                                     text: "Move to front" |                                     text: "Move to front" | ||||||
|                                     onTriggered: mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) |                                     onTriggered: mapModel.moveToFront(mapModelFiltered.mapRowToSource(index)) | ||||||
| @ -360,6 +385,38 @@ Item { | |||||||
|                                     id: coordsMenuItem |                                     id: coordsMenuItem | ||||||
|                                     text: "" |                                     text: "" | ||||||
|                                 } |                                 } | ||||||
|  |                                 Instantiator { | ||||||
|  |                                     model: menus | ||||||
|  |                                     delegate: Menu { | ||||||
|  |                                         //cascade: true | ||||||
|  |                                         id: contextSubMenu | ||||||
|  |                                         title: model.title | ||||||
|  |                                     } | ||||||
|  |                                     onObjectAdded: function(index, object) { | ||||||
|  |                                         contextMenu.insertMenu(index, object) | ||||||
|  |                                     } | ||||||
|  |                                     onObjectRemoved: function(index, object) { | ||||||
|  |                                         contextMenu.removeMenu(object) | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                                 Instantiator { | ||||||
|  |                                     model: menuItems | ||||||
|  |                                     delegate: MenuItem { | ||||||
|  |                                         text: model.text | ||||||
|  |                                         onTriggered: mapModel.setFrequency(model.frequency, model.deviceSet) | ||||||
|  |                                     } | ||||||
|  |                                     onObjectAdded: function(index, object) { | ||||||
|  |                                         // index is index in to menuItems model | ||||||
|  |                                         // object is the MenuItem | ||||||
|  |                                         var menuItem = menuItems.get(index) | ||||||
|  |                                         var menu = menus.get(menuItem.menuIndex) | ||||||
|  |                                         contextMenu.menuAt(menuItem.menuIndex).insertItem(index, object) | ||||||
|  |                                     } | ||||||
|  |                                     onObjectRemoved: function(index, object) { | ||||||
|  |                                         // Can't use menuItems.get(index) here, as already removed from model | ||||||
|  |                                         object.menu.removeItem(object) | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -1189,11 +1189,12 @@ void MapGUI::applyMap2DSettings(bool reloadMap) | |||||||
|             if (!m_settings.m_mapBoxStyles.isEmpty()) |             if (!m_settings.m_mapBoxStyles.isEmpty()) | ||||||
|                 parameters["mapboxgl.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles; |                 parameters["mapboxgl.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles; | ||||||
|         } |         } | ||||||
|         if (m_settings.m_mapProvider == "maplibre") |         if (m_settings.m_mapProvider == "maplibregl") | ||||||
|         { |         { | ||||||
|             parameters["maplibre.access_token"] = m_settings.m_mapBoxAPIKey; |             parameters["maplibregl.settings_template"] = "maptiler"; // Or "mapbox"
 | ||||||
|  |             parameters["maplibregl.access_token"] = m_settings.m_maptilerAPIKey; | ||||||
|             if (!m_settings.m_mapBoxStyles.isEmpty()) |             if (!m_settings.m_mapBoxStyles.isEmpty()) | ||||||
|                 parameters["maplibre.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles; |                 parameters["maplibregl.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles; | ||||||
|         } |         } | ||||||
|         if (m_settings.m_mapProvider == "osm") |         if (m_settings.m_mapProvider == "osm") | ||||||
|         { |         { | ||||||
|  | |||||||
| @ -90,7 +90,7 @@ void ObjectMapItem::update(SWGSDRangel::SWGMapItem *mapItem) | |||||||
|             m_animations.append(new CesiumInterface::Animation(animation)); |             m_animations.append(new CesiumInterface::Animation(animation)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     findFrequency(); |     findFrequencies(); | ||||||
|     if (!m_fixedPosition) |     if (!m_fixedPosition) | ||||||
|     { |     { | ||||||
|         updateTrack(mapItem->getTrack()); |         updateTrack(mapItem->getTrack()); | ||||||
| @ -192,29 +192,33 @@ void PolylineMapItem::update(SWGSDRangel::SWGMapItem *mapItem) | |||||||
|     m_bounds = QGeoRectangle(QGeoCoordinate(latMax, lonMin), QGeoCoordinate(latMin, lonMax)); |     m_bounds = QGeoRectangle(QGeoCoordinate(latMax, lonMin), QGeoCoordinate(latMin, lonMax)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ObjectMapItem::findFrequency() | // Look for a frequency in the text for this object
 | ||||||
|  | void ObjectMapItem::findFrequencies() | ||||||
| { | { | ||||||
|     // Look for a frequency in the text for this object
 |     m_frequencies.clear(); | ||||||
|     QRegExp re("(([0-9]+(\\.[0-9]+)?) *([kMG])?Hz)"); |     m_frequencyStrings.clear(); | ||||||
|     if (re.indexIn(m_text) != -1) | 
 | ||||||
|  |     const QRegularExpression re("(([0-9]+(\\.[0-9]+)?) *([kMG])?Hz)"); | ||||||
|  |     QRegularExpressionMatchIterator itr = re.globalMatch(m_text); | ||||||
|  |     while (itr.hasNext()) | ||||||
|     { |     { | ||||||
|         QStringList capture = re.capturedTexts(); |         QRegularExpressionMatch match = itr.next(); | ||||||
|         m_frequency = capture[2].toDouble(); |         QStringList capture = match.capturedTexts(); | ||||||
|  |         double frequency = capture[2].toDouble(); | ||||||
|  | 
 | ||||||
|         if (capture.length() == 5) |         if (capture.length() == 5) | ||||||
|         { |         { | ||||||
|             QChar unit = capture[4][0]; |             QChar unit = capture[4][0]; | ||||||
|             if (unit == 'k') |             if (unit == 'k') { | ||||||
|                 m_frequency *= 1000.0; |                 frequency *= 1000; | ||||||
|             else if (unit == 'M') |             } else if (unit == 'M') { | ||||||
|                 m_frequency *= 1000000.0; |                 frequency *= 1000000; | ||||||
|             else if (unit == 'G') |             } else if (unit == 'G') { | ||||||
|                 m_frequency *= 1000000000.0; |                 frequency *= 1000000000; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         m_frequencyString = capture[0]; |         m_frequencies.append((qint64)frequency); | ||||||
|     } |         m_frequencyStrings.append(capture[0]); | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         m_frequency = 0.0; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -77,7 +77,7 @@ public: | |||||||
|     void update(SWGSDRangel::SWGMapItem *mapItem) override; |     void update(SWGSDRangel::SWGMapItem *mapItem) override; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|     void findFrequency(); |     void findFrequencies(); | ||||||
|     void updateTrack(QList<SWGSDRangel::SWGMapCoordinate *> *track); |     void updateTrack(QList<SWGSDRangel::SWGMapCoordinate *> *track); | ||||||
|     void updatePredictedTrack(QList<SWGSDRangel::SWGMapCoordinate *> *track); |     void updatePredictedTrack(QList<SWGSDRangel::SWGMapCoordinate *> *track); | ||||||
| 
 | 
 | ||||||
| @ -92,8 +92,8 @@ protected: | |||||||
|     QString m_image; |     QString m_image; | ||||||
|     int m_imageRotation; |     int m_imageRotation; | ||||||
|     QString m_text; |     QString m_text; | ||||||
|     double m_frequency;                 // Frequency to set
 |     QList<qint64> m_frequencies;        // Frequencies that can be tuned (currently only extracted from text)
 | ||||||
|     QString m_frequencyString; |     QStringList m_frequencyStrings; | ||||||
|     bool m_fixedPosition;               // Don't record/display track
 |     bool m_fixedPosition;               // Don't record/display track
 | ||||||
|     QList<QGeoCoordinate *> m_predictedTrackCoords; |     QList<QGeoCoordinate *> m_predictedTrackCoords; | ||||||
|     QList<QDateTime *> m_predictedTrackDateTimes; |     QList<QDateTime *> m_predictedTrackDateTimes; | ||||||
|  | |||||||
| @ -516,8 +516,8 @@ QHash<int, QByteArray> ObjectMapModel::roleNames() const | |||||||
|     roles[bubbleColourRole] = "bubbleColour"; |     roles[bubbleColourRole] = "bubbleColour"; | ||||||
|     roles[selectedRole] = "selected"; |     roles[selectedRole] = "selected"; | ||||||
|     roles[targetRole] = "target"; |     roles[targetRole] = "target"; | ||||||
|     roles[frequencyRole] = "frequency"; |     roles[frequenciesRole] = "frequencies"; | ||||||
|     roles[frequencyStringRole] = "frequencyString"; |     roles[frequencyStringsRole] = "frequencyStrings"; | ||||||
|     roles[predictedGroundTrack1Role] = "predictedGroundTrack1"; |     roles[predictedGroundTrack1Role] = "predictedGroundTrack1"; | ||||||
|     roles[predictedGroundTrack2Role] = "predictedGroundTrack2"; |     roles[predictedGroundTrack2Role] = "predictedGroundTrack2"; | ||||||
|     roles[groundTrack1Role] = "groundTrack1"; |     roles[groundTrack1Role] = "groundTrack1"; | ||||||
| @ -675,10 +675,10 @@ QVariant ObjectMapModel::data(const QModelIndex &index, int role) const | |||||||
|         return QVariant::fromValue(m_selected[row]); |         return QVariant::fromValue(m_selected[row]); | ||||||
|     case targetRole: |     case targetRole: | ||||||
|         return QVariant::fromValue(m_target == row); |         return QVariant::fromValue(m_target == row); | ||||||
|     case frequencyRole: |     case frequenciesRole: | ||||||
|         return QVariant::fromValue(mapItem->m_frequency); |         return QVariant::fromValue(mapItem->m_frequencies); | ||||||
|     case frequencyStringRole: |     case frequencyStringsRole: | ||||||
|         return QVariant::fromValue(mapItem->m_frequencyString); |         return QVariant::fromValue(mapItem->m_frequencyStrings); | ||||||
|     case predictedGroundTrack1Role: |     case predictedGroundTrack1Role: | ||||||
|     { |     { | ||||||
|         if (   (m_displayAllGroundTracks || (m_displaySelectedGroundTracks && m_selected[row])) |         if (   (m_displayAllGroundTracks || (m_displaySelectedGroundTracks && m_selected[row])) | ||||||
| @ -780,12 +780,6 @@ void ObjectMapModel::setDisplayAllGroundTracks(bool displayGroundTracks) | |||||||
|     allUpdated(); |     allUpdated(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ObjectMapModel::setFrequency(double frequency) |  | ||||||
| { |  | ||||||
|     // Set as centre frequency
 |  | ||||||
|     ChannelWebAPIUtils::setCenterFrequency(0, frequency); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ObjectMapModel::track3D(int index) | void ObjectMapModel::track3D(int index) | ||||||
| { | { | ||||||
|     if (index < m_items.count()) |     if (index < m_items.count()) | ||||||
| @ -795,6 +789,22 @@ void ObjectMapModel::track3D(int index) | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | QStringList ObjectMapModel::getDeviceSets() const | ||||||
|  | { | ||||||
|  |     return MainCore::instance()->getDeviceSetIds(true, true, false); // FIXME: MIMO currently disabled, as we can't get channel stream indexes
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ObjectMapModel::setFrequency(qint64 frequency, const QString& deviceSetId) | ||||||
|  | { | ||||||
|  |     unsigned int deviceSetIndex; | ||||||
|  | 
 | ||||||
|  |     if (MainCore::getDeviceSetIndexFromId(deviceSetId, deviceSetIndex)) | ||||||
|  |     { | ||||||
|  |         // Set as centre frequency
 | ||||||
|  |         ChannelWebAPIUtils::setCenterFrequency(deviceSetIndex, frequency); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ObjectMapModel::splitTracks(ObjectMapItem *item) | void ObjectMapModel::splitTracks(ObjectMapItem *item) | ||||||
| { | { | ||||||
|     if (item->m_takenTrackCoords.size() > 1) |     if (item->m_takenTrackCoords.size() > 1) | ||||||
|  | |||||||
| @ -211,8 +211,8 @@ public: | |||||||
|         bubbleColourRole = MapModel::lastRole + 4, |         bubbleColourRole = MapModel::lastRole + 4, | ||||||
|         selectedRole = MapModel::lastRole + 5, |         selectedRole = MapModel::lastRole + 5, | ||||||
|         targetRole = MapModel::lastRole + 6, |         targetRole = MapModel::lastRole + 6, | ||||||
|         frequencyRole = MapModel::lastRole + 7, |         frequenciesRole = MapModel::lastRole + 7, | ||||||
|         frequencyStringRole = MapModel::lastRole + 8, |         frequencyStringsRole = MapModel::lastRole + 8, | ||||||
|         predictedGroundTrack1Role = MapModel::lastRole + 9, |         predictedGroundTrack1Role = MapModel::lastRole + 9, | ||||||
|         predictedGroundTrack2Role = MapModel::lastRole + 10, |         predictedGroundTrack2Role = MapModel::lastRole + 10, | ||||||
|         groundTrack1Role = MapModel::lastRole + 11, |         groundTrack1Role = MapModel::lastRole + 11, | ||||||
| @ -244,8 +244,10 @@ public: | |||||||
|     void setDisplayNames(bool displayNames); |     void setDisplayNames(bool displayNames); | ||||||
|     void setDisplaySelectedGroundTracks(bool displayGroundTracks); |     void setDisplaySelectedGroundTracks(bool displayGroundTracks); | ||||||
|     void setDisplayAllGroundTracks(bool displayGroundTracks); |     void setDisplayAllGroundTracks(bool displayGroundTracks); | ||||||
|     Q_INVOKABLE void setFrequency(double frequency); |  | ||||||
|     Q_INVOKABLE void track3D(int index); |     Q_INVOKABLE void track3D(int index); | ||||||
|  |     Q_INVOKABLE QStringList getDeviceSets() const; | ||||||
|  |     Q_INVOKABLE void setFrequency(qint64 frequency, const QString& deviceSet); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     Q_INVOKABLE void viewChanged(double bottomLeftLongitude, double bottomRightLongitude); |     Q_INVOKABLE void viewChanged(double bottomLeftLongitude, double bottomRightLongitude); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -66,7 +66,7 @@ const QStringList MapSettings::m_mapProviders = { | |||||||
|     QStringLiteral("esri"), |     QStringLiteral("esri"), | ||||||
|     QStringLiteral("mapbox"), |     QStringLiteral("mapbox"), | ||||||
|     QStringLiteral("mapboxgl"), |     QStringLiteral("mapboxgl"), | ||||||
|     QStringLiteral("maplibre") |     QStringLiteral("maplibregl") | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| MapSettings::MapSettings() : | MapSettings::MapSettings() : | ||||||
|  | |||||||
| @ -95,7 +95,7 @@ | |||||||
|                </item> |                </item> | ||||||
|                <item> |                <item> | ||||||
|                 <property name="text"> |                 <property name="text"> | ||||||
|                  <string>MapLibre</string> |                  <string>MapLibreGL</string> | ||||||
|                 </property> |                 </property> | ||||||
|                </item> |                </item> | ||||||
|               </widget> |               </widget> | ||||||
|  | |||||||
| @ -501,13 +501,10 @@ void StarTrackerWorker::update() | |||||||
|     { |     { | ||||||
|         // Get Az/El from Satellite Tracker
 |         // Get Az/El from Satellite Tracker
 | ||||||
|         double azimuth, elevation; |         double azimuth, elevation; | ||||||
|  |         unsigned int satelliteTrackerFeatureSetIndex,satelliteTrackerFeatureIndex; | ||||||
| 
 | 
 | ||||||
|         const QRegExp re("F([0-9]+):([0-9]+)"); |         if (MainCore::getFeatureIndexFromId(m_settings.m_target, satelliteTrackerFeatureSetIndex, satelliteTrackerFeatureIndex)) | ||||||
|         if (re.indexIn(m_settings.m_target) >= 0) |  | ||||||
|         { |         { | ||||||
|             int satelliteTrackerFeatureSetIndex = re.capturedTexts()[1].toInt(); |  | ||||||
|             int satelliteTrackerFeatureIndex = re.capturedTexts()[2].toInt(); |  | ||||||
| 
 |  | ||||||
|             if (ChannelWebAPIUtils::getFeatureReportValue(satelliteTrackerFeatureSetIndex, satelliteTrackerFeatureIndex, "targetAzimuth", azimuth) |             if (ChannelWebAPIUtils::getFeatureReportValue(satelliteTrackerFeatureSetIndex, satelliteTrackerFeatureIndex, "targetAzimuth", azimuth) | ||||||
|                 && ChannelWebAPIUtils::getFeatureReportValue(satelliteTrackerFeatureSetIndex, satelliteTrackerFeatureIndex, "targetElevation", elevation)) |                 && ChannelWebAPIUtils::getFeatureReportValue(satelliteTrackerFeatureSetIndex, satelliteTrackerFeatureIndex, "targetElevation", elevation)) | ||||||
|             { |             { | ||||||
|  | |||||||
| @ -333,10 +333,11 @@ bool ChannelWebAPIUtils::getCenterFrequency(unsigned int deviceIndex, double &fr | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Set device center frequency
 | // Set device center frequency
 | ||||||
|  | // Doesn't support MIMO devices. We'd need stream index parameter
 | ||||||
| bool ChannelWebAPIUtils::setCenterFrequency(unsigned int deviceIndex, double frequencyInHz) | bool ChannelWebAPIUtils::setCenterFrequency(unsigned int deviceIndex, double frequencyInHz) | ||||||
| { | { | ||||||
|     SWGSDRangel::SWGDeviceSettings deviceSettingsResponse; |     SWGSDRangel::SWGDeviceSettings deviceSettingsResponse; | ||||||
|     int httpRC; |     int httpRC = 404; | ||||||
|     DeviceSet *deviceSet; |     DeviceSet *deviceSet; | ||||||
| 
 | 
 | ||||||
|     if (getDeviceSettings(deviceIndex, deviceSettingsResponse, deviceSet)) |     if (getDeviceSettings(deviceIndex, deviceSettingsResponse, deviceSet)) | ||||||
| @ -354,8 +355,13 @@ bool ChannelWebAPIUtils::setCenterFrequency(unsigned int deviceIndex, double fre | |||||||
|             SWGSDRangel::SWGErrorResponse errorResponse2; |             SWGSDRangel::SWGErrorResponse errorResponse2; | ||||||
| 
 | 
 | ||||||
|             DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); |             DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); | ||||||
| 
 |             if (source) { | ||||||
|             httpRC = source->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); |                 httpRC = source->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); | ||||||
|  |             } | ||||||
|  |             DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); | ||||||
|  |             if (sink) { | ||||||
|  |                 httpRC = sink->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             if (httpRC/100 == 2) |             if (httpRC/100 == 2) | ||||||
|             { |             { | ||||||
|  | |||||||
| @ -435,6 +435,121 @@ void MainCore::updateWakeLock() | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | QChar MainCore::getDeviceSetTypeId(const DeviceSet* deviceSet) | ||||||
|  | { | ||||||
|  |     if (deviceSet->m_deviceMIMOEngine) { | ||||||
|  |         return 'M'; | ||||||
|  |     } else if (deviceSet->m_deviceSinkEngine) { | ||||||
|  |         return 'T'; | ||||||
|  |     } else if (deviceSet->m_deviceSourceEngine) { | ||||||
|  |         return 'R'; | ||||||
|  |     } else { | ||||||
|  |         return 'X'; // Unknown
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QString MainCore::getDeviceSetId(const DeviceSet* deviceSet) | ||||||
|  | { | ||||||
|  |     QChar type = getDeviceSetTypeId(deviceSet); | ||||||
|  | 
 | ||||||
|  |     return QString("%1%2").arg(type).arg(deviceSet->getIndex()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QString MainCore::getChannelId(const ChannelAPI* channel) | ||||||
|  | { | ||||||
|  |     std::vector<DeviceSet*> deviceSets = getDeviceSets(); | ||||||
|  |     DeviceSet* deviceSet = deviceSets[channel->getDeviceSetIndex()]; | ||||||
|  |     QString deviceSetId = getDeviceSetId(deviceSet); | ||||||
|  |     int index = channel->getIndexInDeviceSet(); | ||||||
|  |     // FIXME: if (deviceSet->m_deviceMIMOEngine) {
 | ||||||
|  |     // we should append stream index. E.g. "M0:0.0" However, only ChannelGUI seems to know what it is
 | ||||||
|  |     return QString("%1:%2").arg(deviceSetId).arg(index); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QStringList MainCore::getDeviceSetIds(bool rx, bool tx, bool mimo) | ||||||
|  | { | ||||||
|  |     QStringList list; | ||||||
|  |     std::vector<DeviceSet*> deviceSets = getDeviceSets(); | ||||||
|  | 
 | ||||||
|  |     for (const auto deviceSet : deviceSets) | ||||||
|  |     { | ||||||
|  |         DSPDeviceSourceEngine *deviceSourceEngine = deviceSet->m_deviceSourceEngine; | ||||||
|  |         DSPDeviceSinkEngine *deviceSinkEngine = deviceSet->m_deviceSinkEngine; | ||||||
|  |         DSPDeviceMIMOEngine *deviceMIMOEngine = deviceSet->m_deviceMIMOEngine; | ||||||
|  | 
 | ||||||
|  |         if (((deviceSourceEngine != nullptr) && rx) | ||||||
|  |             || ((deviceSinkEngine != nullptr) && tx) | ||||||
|  |             || ((deviceMIMOEngine != nullptr) && mimo)) | ||||||
|  |         { | ||||||
|  |             list.append(getDeviceSetId(deviceSet)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return list; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool MainCore::getDeviceSetTypeFromId(const QString& deviceSetId, QChar &type) | ||||||
|  | { | ||||||
|  |     if (!deviceSetId.isEmpty()) | ||||||
|  |     { | ||||||
|  |         type = deviceSetId[0]; | ||||||
|  |         return (type == 'R') || (type == 'T') || (type == 'M'); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool MainCore::getDeviceSetIndexFromId(const QString& deviceSetId, unsigned int &deviceSetIndex) | ||||||
|  | { | ||||||
|  |     const QRegularExpression re("[RTM]([0-9]+)"); | ||||||
|  |     QRegularExpressionMatch match = re.match(deviceSetId); | ||||||
|  | 
 | ||||||
|  |     if (match.hasMatch()) | ||||||
|  |     { | ||||||
|  |         deviceSetIndex = match.capturedTexts()[1].toInt(); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool MainCore::getDeviceAndChannelIndexFromId(const QString& channelId, unsigned int &deviceSetIndex, unsigned int &channelIndex) | ||||||
|  | { | ||||||
|  |     const QRegularExpression re("[RTM]([0-9]+):([0-9]+)"); | ||||||
|  |     QRegularExpressionMatch match = re.match(channelId); | ||||||
|  | 
 | ||||||
|  |     if (match.hasMatch()) | ||||||
|  |     { | ||||||
|  |         deviceSetIndex = match.capturedTexts()[1].toInt(); | ||||||
|  |         channelIndex = match.capturedTexts()[2].toInt(); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool MainCore::getFeatureIndexFromId(const QString& featureId, unsigned int &featureSetIndex, unsigned int &featureIndex) | ||||||
|  | { | ||||||
|  |     const QRegularExpression re("[F]([0-9]+):([0-9]+)"); | ||||||
|  |     QRegularExpressionMatch match = re.match(featureId); | ||||||
|  | 
 | ||||||
|  |     if (match.hasMatch()) | ||||||
|  |     { | ||||||
|  |         featureSetIndex = match.capturedTexts()[1].toInt(); | ||||||
|  |         featureIndex = match.capturedTexts()[2].toInt(); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::vector<ChannelAPI*> MainCore::getChannels(const QString& uri) | std::vector<ChannelAPI*> MainCore::getChannels(const QString& uri) | ||||||
| { | { | ||||||
|     std::vector<ChannelAPI*> channels; |     std::vector<ChannelAPI*> channels; | ||||||
| @ -452,3 +567,15 @@ std::vector<ChannelAPI*> MainCore::getChannels(const QString& uri) | |||||||
| 
 | 
 | ||||||
|     return channels; |     return channels; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | QStringList MainCore::getChannelIds(const QString& uri) | ||||||
|  | { | ||||||
|  |     QStringList list; | ||||||
|  |     std::vector<ChannelAPI*> channels = getChannels(uri); | ||||||
|  | 
 | ||||||
|  |     for (const auto channel : channels) { | ||||||
|  |         list.append(getChannelId(channel)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return list; | ||||||
|  | } | ||||||
|  | |||||||
| @ -857,7 +857,6 @@ public: | |||||||
|     PluginManager *getPluginManager() const { return m_pluginManager; } |     PluginManager *getPluginManager() const { return m_pluginManager; } | ||||||
|     std::vector<DeviceSet*>& getDeviceSets() { return m_deviceSets; } |     std::vector<DeviceSet*>& getDeviceSets() { return m_deviceSets; } | ||||||
|     std::vector<FeatureSet*>& getFeatureeSets() { return m_featureSets; } |     std::vector<FeatureSet*>& getFeatureeSets() { return m_featureSets; } | ||||||
|     std::vector<ChannelAPI*> getChannels(const QString& uri); //!< Get all channels from any device set with the given URI
 |  | ||||||
|     void setLoggingOptions(); |     void setLoggingOptions(); | ||||||
|     DeviceAPI *getDevice(unsigned int deviceSetIndex); |     DeviceAPI *getDevice(unsigned int deviceSetIndex); | ||||||
|     ChannelAPI *getChannel(unsigned int deviceSetIndex, int channelIndex); |     ChannelAPI *getChannel(unsigned int deviceSetIndex, int channelIndex); | ||||||
| @ -887,6 +886,18 @@ public: | |||||||
|     // Position
 |     // Position
 | ||||||
|     const QGeoPositionInfo& getPosition() const; |     const QGeoPositionInfo& getPosition() const; | ||||||
| 
 | 
 | ||||||
|  |     // Ids
 | ||||||
|  |     QChar getDeviceSetTypeId(const DeviceSet* deviceSet); //!< Get Type Id (E.g. 'R', 'T' or 'M') for the given device set
 | ||||||
|  |     QString getDeviceSetId(const DeviceSet* deviceSet); //!< Get Id (E.g. "R2") for the given device set
 | ||||||
|  |     QString getChannelId(const ChannelAPI* channel); //!< Get Id (E.g. "R1:2") for the given channel
 | ||||||
|  |     static bool getDeviceSetTypeFromId(const QString& deviceSetId, QChar &type); //!< "R1" -> 'R'
 | ||||||
|  |     static bool getDeviceSetIndexFromId(const QString& deviceSetId, unsigned int &deviceSetIndex); //!< "R1" -> 1
 | ||||||
|  |     static bool getDeviceAndChannelIndexFromId(const QString& channelId, unsigned int &deviceSetIndex, unsigned int &channelIndex); //!< "R3:4" -> 3, 4
 | ||||||
|  |     static bool getFeatureIndexFromId(const QString& featureId, unsigned int &featureSetIndex, unsigned int &featureIndex); //!< "F0:2" -> 0, 2
 | ||||||
|  |     QStringList getDeviceSetIds(bool rx, bool tx, bool mimo); //!< Get list of all device set Ids. E.g: {"R0", "R1", "T1", "M2"}
 | ||||||
|  |     std::vector<ChannelAPI*> getChannels(const QString& uri); //!< Get all channels from any device set with the given URI
 | ||||||
|  |     QStringList getChannelIds(const QString& uri); //!< Get all Ids for channels from any device set with the given URI. E.g. "sdrangel.channel.xyzdemod" -> {"R2:1", "M0:0.1"}
 | ||||||
|  | 
 | ||||||
|     friend class MainServer; |     friend class MainServer; | ||||||
|     friend class MainWindow; |     friend class MainWindow; | ||||||
|     friend class WebAPIAdapter; |     friend class WebAPIAdapter; | ||||||
|  | |||||||
| @ -1502,10 +1502,17 @@ void MainWindow::loadConfiguration(const Configuration *configuration, bool from | |||||||
|                 deviceWorkspaceIndex; |                 deviceWorkspaceIndex; | ||||||
|             sampleMIMOAdd(m_workspaces[deviceWorkspaceIndex], m_workspaces[spectrumWorkspaceIndex], bestDeviceIndex); |             sampleMIMOAdd(m_workspaces[deviceWorkspaceIndex], m_workspaces[spectrumWorkspaceIndex], bestDeviceIndex); | ||||||
|         } |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             qDebug() << "MainWindow::loadConfiguration: Unknown preset type: " << deviceSetPreset.getPresetType(); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         MDIUtils::restoreMDIGeometry(m_deviceUIs.back()->m_deviceGUI, deviceSetPreset.getDeviceGeometry()); |         if (m_deviceUIs.size() > 0) | ||||||
|         MDIUtils::restoreMDIGeometry(m_deviceUIs.back()->m_mainSpectrumGUI, deviceSetPreset.getSpectrumGeometry()); |         { | ||||||
|         m_deviceUIs.back()->loadDeviceSetSettings(&deviceSetPreset, m_pluginManager->getPluginAPI(), &m_workspaces, nullptr); |             MDIUtils::restoreMDIGeometry(m_deviceUIs.back()->m_deviceGUI, deviceSetPreset.getDeviceGeometry()); | ||||||
|  |             MDIUtils::restoreMDIGeometry(m_deviceUIs.back()->m_mainSpectrumGUI, deviceSetPreset.getSpectrumGeometry()); | ||||||
|  |             m_deviceUIs.back()->loadDeviceSetSettings(&deviceSetPreset, m_pluginManager->getPluginAPI(), &m_workspaces, nullptr); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (waitBox) |         if (waitBox) | ||||||
|         { |         { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user