| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2016 Edouard Griffiths, F4EXB                                   //
 | 
					
						
							|  |  |  | // Copyright (C) 2023 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          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							|  |  |  | // (at your option) any later version.                                           //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include <QAction>
 | 
					
						
							|  |  |  | #include <QClipboard>
 | 
					
						
							|  |  |  | #include <QMenu>
 | 
					
						
							|  |  |  | #include <QTableWidget>
 | 
					
						
							|  |  |  | #include <QTableWidgetItem>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "device/deviceset.h"
 | 
					
						
							|  |  |  | #include "device/deviceuiset.h"
 | 
					
						
							|  |  |  | #include "dsp/dspengine.h"
 | 
					
						
							|  |  |  | #include "dsp/dspcommands.h"
 | 
					
						
							|  |  |  | #include "ui_freqscannergui.h"
 | 
					
						
							|  |  |  | #include "util/simpleserializer.h"
 | 
					
						
							|  |  |  | #include "util/db.h"
 | 
					
						
							|  |  |  | #include "gui/basicchannelsettingsdialog.h"
 | 
					
						
							|  |  |  | #include "dsp/dspengine.h"
 | 
					
						
							|  |  |  | #include "dsp/glscopesettings.h"
 | 
					
						
							|  |  |  | #include "gui/tabletapandhold.h"
 | 
					
						
							|  |  |  | #include "gui/dialogpositioner.h"
 | 
					
						
							|  |  |  | #include "gui/decimaldelegate.h"
 | 
					
						
							|  |  |  | #include "gui/frequencydelegate.h"
 | 
					
						
							|  |  |  | #include "gui/glspectrum.h"
 | 
					
						
							|  |  |  | #include "channel/channelwebapiutils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "freqscannergui.h"
 | 
					
						
							|  |  |  | #include "freqscanneraddrangedialog.h"
 | 
					
						
							|  |  |  | #include "freqscanner.h"
 | 
					
						
							|  |  |  | #include "freqscannersink.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FreqScannerGUI* FreqScannerGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     FreqScannerGUI* gui = new FreqScannerGUI(pluginAPI, deviceUISet, rxChannel); | 
					
						
							|  |  |  |     return gui; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::destroy() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::resetToDefaults() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.resetToDefaults(); | 
					
						
							|  |  |  |     displaySettings(); | 
					
						
							|  |  |  |     applyAllSettings(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QByteArray FreqScannerGUI::serialize() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_settings.serialize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FreqScannerGUI::deserialize(const QByteArray& data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(m_settings.deserialize(data)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         displaySettings(); | 
					
						
							|  |  |  |         applyAllSettings(); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         resetToDefaults(); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FreqScannerGUI::handleMessage(const Message& message) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (FreqScanner::MsgConfigureFreqScanner::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("FreqScannerGUI::handleMessage: FreqScanner::MsgConfigureFreqScanner"); | 
					
						
							|  |  |  |         const FreqScanner::MsgConfigureFreqScanner& cfg = (FreqScanner::MsgConfigureFreqScanner&) message; | 
					
						
							|  |  |  |         m_settings = cfg.getSettings(); | 
					
						
							|  |  |  |         blockApplySettings(true); | 
					
						
							|  |  |  |         m_channelMarker.updateSettings(static_cast<const ChannelMarker*>(m_settings.m_channelMarker)); | 
					
						
							|  |  |  |         displaySettings(); | 
					
						
							|  |  |  |         blockApplySettings(false); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (DSPSignalNotification::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPSignalNotification& notif = (DSPSignalNotification&) message; | 
					
						
							|  |  |  |         m_deviceCenterFrequency = notif.getCenterFrequency(); | 
					
						
							|  |  |  |         m_basebandSampleRate = notif.getSampleRate(); | 
					
						
							| 
									
										
										
										
											2023-10-13 07:54:43 +00:00
										 |  |  |         if (m_basebandSampleRate != 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             ui->deltaFrequency->setValueRange(true, 7, 0, m_basebandSampleRate/2); | 
					
						
							|  |  |  |             ui->deltaFrequencyLabel->setToolTip(tr("Range %1 %L2 Hz").arg(QChar(0xB1)).arg(m_basebandSampleRate/2)); | 
					
						
							|  |  |  |             ui->channelBandwidth->setValueRange(true, 7, 0, m_basebandSampleRate); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |         if (m_channelMarker.getBandwidth() == 0) { | 
					
						
							|  |  |  |             m_channelMarker.setBandwidth(m_basebandSampleRate); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         updateAbsoluteCenterFrequency(); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgReportChannels::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgReportChannels& report = (FreqScanner::MsgReportChannels&)message; | 
					
						
							|  |  |  |         updateChannelsList(report.getChannels()); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgStatus::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgStatus& report = (FreqScanner::MsgStatus&)message; | 
					
						
							|  |  |  |         ui->status->setText(report.getText()); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgReportScanning::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ui->status->setText("Scanning"); | 
					
						
							|  |  |  |         ui->table->clearSelection(); | 
					
						
							|  |  |  |         ui->channelPower->setText("-"); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgScanComplete::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ui->startStop->setChecked(false); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgReportActiveFrequency::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgReportActiveFrequency& report = (FreqScanner::MsgReportActiveFrequency&)message; | 
					
						
							|  |  |  |         qint64 f = report.getCenterFrequency(); | 
					
						
							|  |  |  |         QString frequency; | 
					
						
							|  |  |  |         QString annotation; | 
					
						
							|  |  |  |         QList<QTableWidgetItem*> items = ui->table->findItems(QString::number(f), Qt::MatchExactly); | 
					
						
							|  |  |  |         if (items.size() > 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             ui->table->selectRow(items[0]->row()); | 
					
						
							|  |  |  |             frequency = ui->table->item(items[0]->row(), COL_FREQUENCY)->text(); | 
					
						
							|  |  |  |             annotation = ui->table->item(items[0]->row(), COL_ANNOTATION)->text(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         FrequencyDelegate freqDelegate("Auto", 3); | 
					
						
							|  |  |  |         QString formattedFrequency = freqDelegate.displayText(frequency, QLocale::system()); | 
					
						
							|  |  |  |         ui->status->setText(QString("Active: %1 %2").arg(formattedFrequency).arg(annotation)); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgReportActivePower::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgReportActivePower& report = (FreqScanner::MsgReportActivePower&)message; | 
					
						
							|  |  |  |         float power = report.getPower(); | 
					
						
							|  |  |  |         ui->channelPower->setText(QString::number(power, 'f', 1)); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgReportScanRange::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgReportScanRange& report = (FreqScanner::MsgReportScanRange&)message; | 
					
						
							|  |  |  |         m_channelMarker.setCenterFrequency(report.getCenterFrequency()); | 
					
						
							|  |  |  |         m_channelMarker.setBandwidth(report.getTotalBandwidth()); | 
					
						
							| 
									
										
										
										
											2023-10-03 15:09:54 +00:00
										 |  |  |         m_channelMarker.setVisible(report.getTotalBandwidth() < m_basebandSampleRate); // Hide marker if full bandwidth
 | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (FreqScanner::MsgScanResult::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgScanResult& report = (FreqScanner::MsgScanResult&)message; | 
					
						
							|  |  |  |         QList<FreqScanner::MsgScanResult::ScanResult> results = report.getScanResults(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Clear column
 | 
					
						
							|  |  |  |         for (int i = 0; i < ui->table->rowCount(); i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QTableWidgetItem* item = ui->table->item(i, COL_POWER); | 
					
						
							|  |  |  |             item->setText(""); | 
					
						
							|  |  |  |             item->setBackground(QBrush()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // Add results
 | 
					
						
							|  |  |  |         for (int i = 0; i < results.size(); i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qint64 freq = results[i].m_frequency; | 
					
						
							|  |  |  |             QList<QTableWidgetItem *> items = ui->table->findItems(QString::number(freq), Qt::MatchExactly); | 
					
						
							|  |  |  |             for (auto item : items) { | 
					
						
							|  |  |  |                 int row = item->row(); | 
					
						
							| 
									
										
										
										
											2023-09-28 18:02:58 +00:00
										 |  |  |                 QTableWidgetItem* powerItem = ui->table->item(row, COL_POWER); | 
					
						
							|  |  |  |                 powerItem->setData(Qt::DisplayRole, results[i].m_power); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |                 bool active = results[i].m_power >= m_settings.m_threshold; | 
					
						
							|  |  |  |                 if (active) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2023-09-28 18:02:58 +00:00
										 |  |  |                     powerItem->setBackground(Qt::darkGreen); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |                     QTableWidgetItem* activeCountItem = ui->table->item(row, COL_ACTIVE_COUNT); | 
					
						
							|  |  |  |                     activeCountItem->setData(Qt::DisplayRole, activeCountItem->data(Qt::DisplayRole).toInt() + 1); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ui->channels->blockSignals(true); | 
					
						
							|  |  |  |     ui->channels->clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const auto& channel : channels) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-29 08:38:15 +00:00
										 |  |  |         // Add channels in this device set, other than ourself (Don't use ChannelGUI::getDeviceSetIndex()/getIndex() as not valid when this is first called)
 | 
					
						
							|  |  |  |         if ((channel.m_deviceSetIndex == m_freqScanner->getDeviceSetIndex()) && (channel.m_channelIndex != m_freqScanner->getIndexInDeviceSet())) | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             QString name = QString("R%1:%2").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex); | 
					
						
							|  |  |  |             ui->channels->addItem(name); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Channel can be created after this plugin, so select it
 | 
					
						
							|  |  |  |     // if the chosen channel appears
 | 
					
						
							|  |  |  |     int channelIndex = ui->channels->findText(m_settings.m_channel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (channelIndex >= 0) { | 
					
						
							|  |  |  |         ui->channels->setCurrentIndex(channelIndex); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         ui->channels->setCurrentIndex(-1); // return to nothing selected
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ui->channels->blockSignals(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_channels_currentIndexChanged(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (index >= 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_settings.m_channel = ui->channels->currentText(); | 
					
						
							|  |  |  |         applySetting("channel"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::handleInputMessages() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Message* message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while ((message = getInputMessageQueue()->pop()) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (handleMessage(*message)) { | 
					
						
							|  |  |  |             delete message; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::channelMarkerChangedByCursor() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::channelMarkerHighlightedByCursor() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setHighlighted(m_channelMarker.getHighlighted()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_deltaFrequency_changed(qint64 value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_channelFrequencyOffset = value; | 
					
						
							|  |  |  |     applySetting("channelFrequencyOffset"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_channelBandwidth_changed(qint64 value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_channelBandwidth = value; | 
					
						
							|  |  |  |     applySetting("channelBandwidth"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_scanTime_valueChanged(int value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ui->scanTimeText->setText(QString("%1 s").arg(value / 10.0, 0, 'f', 1)); | 
					
						
							|  |  |  |     m_settings.m_scanTime = value / 10.0; | 
					
						
							|  |  |  |     applySetting("scanTime"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_retransmitTime_valueChanged(int value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ui->retransmitTimeText->setText(QString("%1 s").arg(value / 10.0, 0, 'f', 1)); | 
					
						
							|  |  |  |     m_settings.m_retransmitTime = value / 10.0; | 
					
						
							|  |  |  |     applySetting("retransmitTime"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_tuneTime_valueChanged(int value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ui->tuneTimeText->setText(QString("%1 ms").arg(value)); | 
					
						
							|  |  |  |     m_settings.m_tuneTime = value; | 
					
						
							|  |  |  |     applySetting("tuneTime"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_thresh_valueChanged(int value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ui->threshText->setText(QString("%1 dB").arg(value / 10.0, 0, 'f', 1)); | 
					
						
							|  |  |  |     m_settings.m_threshold = value / 10.0; | 
					
						
							|  |  |  |     applySetting("threshold"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_priority_currentIndexChanged(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_priority = (FreqScannerSettings::Priority)index; | 
					
						
							|  |  |  |     applySetting("priority"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_measurement_currentIndexChanged(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_measurement = (FreqScannerSettings::Measurement)index; | 
					
						
							|  |  |  |     applySetting("measurement"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_mode_currentIndexChanged(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_mode = (FreqScannerSettings::Mode)index; | 
					
						
							|  |  |  |     applySetting("mode"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::onWidgetRolled(QWidget* widget, bool rollDown) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) widget; | 
					
						
							|  |  |  |     (void) rollDown; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getRollupContents()->saveState(m_rollupState); | 
					
						
							|  |  |  |     applySetting("rollupState"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::onMenuDialogCalled(const QPoint &p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_contextMenuType == ContextMenuChannelSettings) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BasicChannelSettingsDialog dialog(&m_channelMarker, this); | 
					
						
							|  |  |  |         dialog.setUseReverseAPI(m_settings.m_useReverseAPI); | 
					
						
							|  |  |  |         dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress); | 
					
						
							|  |  |  |         dialog.setReverseAPIPort(m_settings.m_reverseAPIPort); | 
					
						
							|  |  |  |         dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex); | 
					
						
							|  |  |  |         dialog.setReverseAPIChannelIndex(m_settings.m_reverseAPIChannelIndex); | 
					
						
							|  |  |  |         dialog.setDefaultTitle(m_displayedName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_deviceUISet->m_deviceMIMOEngine) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             dialog.setNumberOfStreams(m_freqScanner->getNumberOfDeviceStreams()); | 
					
						
							|  |  |  |             dialog.setStreamIndex(m_settings.m_streamIndex); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dialog.move(p); | 
					
						
							|  |  |  |         new DialogPositioner(&dialog, false); | 
					
						
							|  |  |  |         dialog.exec(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_settings.m_rgbColor = m_channelMarker.getColor().rgb(); | 
					
						
							|  |  |  |         m_settings.m_title = m_channelMarker.getTitle(); | 
					
						
							|  |  |  |         m_settings.m_useReverseAPI = dialog.useReverseAPI(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIPort = dialog.getReverseAPIPort(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIChannelIndex = dialog.getReverseAPIChannelIndex(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         setWindowTitle(m_settings.m_title); | 
					
						
							|  |  |  |         setTitle(m_channelMarker.getTitle()); | 
					
						
							|  |  |  |         setTitleColor(m_settings.m_rgbColor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QList<QString> settingsKeys({ | 
					
						
							| 
									
										
										
										
											2023-10-13 07:54:43 +00:00
										 |  |  |             "rgbColor", | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |             "title", | 
					
						
							|  |  |  |             "useReverseAPI", | 
					
						
							|  |  |  |             "reverseAPIAddress", | 
					
						
							|  |  |  |             "reverseAPIPort", | 
					
						
							|  |  |  |             "reverseAPIDeviceIndex", | 
					
						
							|  |  |  |             "reverseAPIChannelIndex" | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_deviceUISet->m_deviceMIMOEngine) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_settings.m_streamIndex = dialog.getSelectedStreamIndex(); | 
					
						
							|  |  |  |             m_channelMarker.clearStreamIndexes(); | 
					
						
							|  |  |  |             m_channelMarker.addStreamIndex(m_settings.m_streamIndex); | 
					
						
							|  |  |  |             updateIndexLabel(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         applySettings(settingsKeys); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resetContextMenuType(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) : | 
					
						
							|  |  |  |     ChannelGUI(parent), | 
					
						
							|  |  |  |     ui(new Ui::FreqScannerGUI), | 
					
						
							|  |  |  |     m_pluginAPI(pluginAPI), | 
					
						
							|  |  |  |     m_deviceUISet(deviceUISet), | 
					
						
							|  |  |  |     m_channelMarker(this), | 
					
						
							|  |  |  |     m_deviceCenterFrequency(0), | 
					
						
							|  |  |  |     m_doApplySettings(true) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setAttribute(Qt::WA_DeleteOnClose, true); | 
					
						
							|  |  |  |     m_helpURL = "plugins/channelrx/freqscanner/readme.md"; | 
					
						
							|  |  |  |     RollupContents *rollupContents = getRollupContents(); | 
					
						
							|  |  |  |     ui->setupUi(rollupContents); | 
					
						
							|  |  |  |     setSizePolicy(rollupContents->sizePolicy()); | 
					
						
							|  |  |  |     rollupContents->arrangeRollups(); | 
					
						
							|  |  |  |     connect(rollupContents, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); | 
					
						
							|  |  |  |     connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_freqScanner = reinterpret_cast<FreqScanner*>(rxChannel); | 
					
						
							|  |  |  |     m_freqScanner->setMessageQueueToGUI(getInputMessageQueue()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03))); | 
					
						
							|  |  |  |     ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold)); | 
					
						
							|  |  |  |     ui->deltaFrequency->setValueRange(true, 7, 0, 9999999); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ui->channelBandwidth->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow)); | 
					
						
							| 
									
										
										
										
											2023-09-29 07:42:25 +00:00
										 |  |  |     ui->channelBandwidth->setValueRange(true, 7, 0, 9999999); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_channelMarker.setColor(Qt::yellow); | 
					
						
							|  |  |  |     m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset); | 
					
						
							|  |  |  |     m_channelMarker.setTitle("Frequency Scanner"); | 
					
						
							|  |  |  |     m_channelMarker.blockSignals(false); | 
					
						
							| 
									
										
										
										
											2023-10-03 15:09:54 +00:00
										 |  |  |     m_channelMarker.setVisible(true); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     setTitleColor(m_channelMarker.getColor()); | 
					
						
							|  |  |  |     m_settings.setChannelMarker(&m_channelMarker); | 
					
						
							|  |  |  |     m_settings.setRollupState(&m_rollupState); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_deviceUISet->addChannelMarker(&m_channelMarker); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor())); | 
					
						
							|  |  |  |     connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor())); | 
					
						
							|  |  |  |     connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Resize the table using dummy data
 | 
					
						
							|  |  |  |     resizeTable(); | 
					
						
							|  |  |  |     // Allow user to reorder columns
 | 
					
						
							|  |  |  |     ui->table->horizontalHeader()->setSectionsMovable(true); | 
					
						
							|  |  |  |     // Add context menu to allow hiding/showing of columns
 | 
					
						
							|  |  |  |     m_menu = new QMenu(ui->table); | 
					
						
							|  |  |  |     for (int i = 0; i < ui->table->horizontalHeader()->count(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QString text = ui->table->horizontalHeaderItem(i)->text(); | 
					
						
							|  |  |  |         m_menu->addAction(createCheckableItem(text, i, true)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ui->table->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); | 
					
						
							|  |  |  |     connect(ui->table->horizontalHeader(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(columnSelectMenu(QPoint))); | 
					
						
							|  |  |  |     // Get signals when columns change
 | 
					
						
							|  |  |  |     connect(ui->table->horizontalHeader(), SIGNAL(sectionMoved(int, int, int)), SLOT(table_sectionMoved(int, int, int))); | 
					
						
							|  |  |  |     connect(ui->table->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), SLOT(table_sectionResized(int, int, int))); | 
					
						
							|  |  |  |     // Context menu
 | 
					
						
							|  |  |  |     ui->table->setContextMenuPolicy(Qt::CustomContextMenu); | 
					
						
							|  |  |  |     connect(ui->table, &QTableWidget::customContextMenuRequested, this, &FreqScannerGUI::table_customContextMenuRequested); | 
					
						
							|  |  |  |     TableTapAndHold* tableTapAndHold = new TableTapAndHold(ui->table); | 
					
						
							|  |  |  |     connect(tableTapAndHold, &TableTapAndHold::tapAndHold, this, &FreqScannerGUI::table_customContextMenuRequested); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ui->startStop->setStyleSheet(QString("QToolButton{ background-color: blue; } QToolButton:checked{ background-color: green; }")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     displaySettings(); | 
					
						
							|  |  |  |     makeUIConnections(); | 
					
						
							|  |  |  |     applyAllSettings(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ui->table->setItemDelegateForColumn(COL_FREQUENCY, new FrequencyDelegate("Auto", 3)); | 
					
						
							|  |  |  |     ui->table->setItemDelegateForColumn(COL_POWER, new DecimalDelegate(1)); | 
					
						
							| 
									
										
										
										
											2023-10-03 15:09:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     connect(m_deviceUISet->m_spectrum->getSpectrumView(), &GLSpectrumView::updateAnnotations, this, &FreqScannerGUI::updateAnnotations); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FreqScannerGUI::~FreqScannerGUI() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete ui; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::blockApplySettings(bool block) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_doApplySettings = !block; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::applySetting(const QString& settingsKey) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     applySettings({settingsKey}); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::applySettings(const QStringList& settingsKeys, bool force) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_doApplySettings) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgConfigureFreqScanner* message = FreqScanner::MsgConfigureFreqScanner::create(m_settings, settingsKeys, force); | 
					
						
							|  |  |  |         m_freqScanner->getInputMessageQueue()->push(message); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::applyAllSettings() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     applySettings(QStringList(), true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::displaySettings() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_channelMarker.blockSignals(true); | 
					
						
							|  |  |  |     m_channelMarker.setBandwidth(m_basebandSampleRate); | 
					
						
							|  |  |  |     m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset); | 
					
						
							|  |  |  |     m_channelMarker.setTitle(m_settings.m_title); | 
					
						
							|  |  |  |     m_channelMarker.blockSignals(false); | 
					
						
							|  |  |  |     m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setTitleColor(m_settings.m_rgbColor); | 
					
						
							|  |  |  |     setWindowTitle(m_channelMarker.getTitle()); | 
					
						
							|  |  |  |     setTitle(m_channelMarker.getTitle()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blockApplySettings(true); | 
					
						
							| 
									
										
										
										
											2023-09-29 13:35:52 +00:00
										 |  |  |     int channelIndex = ui->channels->findText(m_settings.m_channel); | 
					
						
							|  |  |  |     if (channelIndex >= 0) { | 
					
						
							|  |  |  |         ui->channels->setCurrentIndex(channelIndex); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |     ui->deltaFrequency->setValue(m_settings.m_channelFrequencyOffset); | 
					
						
							|  |  |  |     ui->channelBandwidth->setValue(m_settings.m_channelBandwidth); | 
					
						
							|  |  |  |     ui->scanTime->setValue(m_settings.m_scanTime * 10.0); | 
					
						
							|  |  |  |     ui->scanTimeText->setText(QString("%1 s").arg(m_settings.m_scanTime, 0, 'f', 1)); | 
					
						
							|  |  |  |     ui->retransmitTime->setValue(m_settings.m_retransmitTime * 10.0); | 
					
						
							|  |  |  |     ui->retransmitTimeText->setText(QString("%1 s").arg(m_settings.m_retransmitTime, 0, 'f', 1)); | 
					
						
							|  |  |  |     ui->tuneTime->setValue(m_settings.m_tuneTime); | 
					
						
							|  |  |  |     ui->tuneTimeText->setText(QString("%1 ms").arg(m_settings.m_tuneTime)); | 
					
						
							|  |  |  |     ui->thresh->setValue(m_settings.m_threshold * 10.0); | 
					
						
							|  |  |  |     ui->threshText->setText(QString("%1 dB").arg(m_settings.m_threshold, 0, 'f', 1)); | 
					
						
							|  |  |  |     ui->priority->setCurrentIndex((int)m_settings.m_priority); | 
					
						
							|  |  |  |     ui->measurement->setCurrentIndex((int)m_settings.m_measurement); | 
					
						
							|  |  |  |     ui->mode->setCurrentIndex((int)m_settings.m_mode); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-29 19:58:19 +00:00
										 |  |  |     ui->table->blockSignals(true); | 
					
						
							| 
									
										
										
										
											2023-10-02 14:45:17 +00:00
										 |  |  |     ui->table->setRowCount(0); | 
					
						
							| 
									
										
										
										
											2023-09-29 20:18:27 +00:00
										 |  |  |     for (int i = 0; i < m_settings.m_frequencies.size(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |         addRow(m_settings.m_frequencies[i], m_settings.m_enabled[i], m_settings.m_notes[i]); | 
					
						
							| 
									
										
										
										
											2023-09-29 20:18:27 +00:00
										 |  |  |         updateAnnotation(i); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-29 19:58:19 +00:00
										 |  |  |     ui->table->blockSignals(false); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Order and size columns
 | 
					
						
							|  |  |  |     QHeaderView* header = ui->table->horizontalHeader(); | 
					
						
							|  |  |  |     for (int i = 0; i < m_settings.m_columnSizes.size(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         bool hidden = m_settings.m_columnSizes[i] == 0; | 
					
						
							|  |  |  |         header->setSectionHidden(i, hidden); | 
					
						
							|  |  |  |         m_menu->actions().at(i)->setChecked(!hidden); | 
					
						
							|  |  |  |         if (m_settings.m_columnSizes[i] > 0) { | 
					
						
							|  |  |  |             ui->table->setColumnWidth(i, m_settings.m_columnSizes[i]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         header->moveSection(header->visualIndex(i), m_settings.m_columnIndexes[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     updateIndexLabel(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getRollupContents()->restoreState(m_rollupState); | 
					
						
							|  |  |  |     updateAbsoluteCenterFrequency(); | 
					
						
							|  |  |  |     blockApplySettings(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::leaveEvent(QEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_channelMarker.setHighlighted(false); | 
					
						
							|  |  |  |     ChannelGUI::leaveEvent(event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::enterEvent(EnterEventType* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_channelMarker.setHighlighted(true); | 
					
						
							|  |  |  |     ChannelGUI::enterEvent(event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_startStop_clicked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (checked) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgStartScan* message = FreqScanner::MsgStartScan::create(); | 
					
						
							|  |  |  |         m_freqScanner->getInputMessageQueue()->push(message); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FreqScanner::MsgStopScan* message = FreqScanner::MsgStopScan::create(); | 
					
						
							|  |  |  |         m_freqScanner->getInputMessageQueue()->push(message); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::addRow(qint64 frequency, bool enabled, const QString& notes) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int row = ui->table->rowCount(); | 
					
						
							|  |  |  |     ui->table->setRowCount(row + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Must create before frequency so updateAnnotation can work
 | 
					
						
							|  |  |  |     QTableWidgetItem* annotationItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     annotationItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_ANNOTATION, annotationItem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_FREQUENCY, new QTableWidgetItem(QString("%1").arg(frequency))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QTableWidgetItem *enableItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     enableItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); | 
					
						
							|  |  |  |     enableItem->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_ENABLE, enableItem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QTableWidgetItem* powerItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     powerItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_POWER, powerItem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QTableWidgetItem *activeCountItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     activeCountItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_ACTIVE_COUNT, activeCountItem); | 
					
						
							|  |  |  |     activeCountItem->setData(Qt::DisplayRole, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QTableWidgetItem* notesItem = new QTableWidgetItem(notes); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_NOTES, notesItem); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_addSingle_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     addRow(0, true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_addRange_clicked() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-09-29 07:42:25 +00:00
										 |  |  |     FreqScannerAddRangeDialog dialog(m_settings.m_channelBandwidth, this); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |     new DialogPositioner(&dialog, false); | 
					
						
							|  |  |  |     if (dialog.exec()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-09-29 09:52:21 +00:00
										 |  |  |         blockApplySettings(true); | 
					
						
							| 
									
										
										
										
											2023-10-02 14:45:17 +00:00
										 |  |  |         for (const auto f : dialog.m_frequencies) { | 
					
						
							|  |  |  |             addRow(f, true); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-29 09:52:21 +00:00
										 |  |  |         blockApplySettings(false); | 
					
						
							|  |  |  |         QList<QString> settingsKeys({ | 
					
						
							|  |  |  |             "frequencies", | 
					
						
							|  |  |  |             "enabled", | 
					
						
							|  |  |  |             "notes" | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         applySettings(settingsKeys); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_remove_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<QTableWidgetItem*> items = ui->table->selectedItems(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (auto item : items) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int row = ui->table->row(item); | 
					
						
							|  |  |  |         ui->table->removeRow(row); | 
					
						
							|  |  |  |         m_settings.m_frequencies.removeAt(row); // table_cellChanged isn't called for removeRow
 | 
					
						
							|  |  |  |         m_settings.m_enabled.removeAt(row); | 
					
						
							| 
									
										
										
										
											2023-09-29 13:35:52 +00:00
										 |  |  |         m_settings.m_notes.removeAt(row); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-29 13:35:52 +00:00
										 |  |  |     QList<QString> settingsKeys({ | 
					
						
							|  |  |  |         "frequencies", | 
					
						
							|  |  |  |         "enabled", | 
					
						
							|  |  |  |         "notes" | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     applySettings(settingsKeys); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-02 14:45:17 +00:00
										 |  |  | void FreqScannerGUI::on_removeInactive_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (int i = ui->table->rowCount() - 1; i >= 0; i--) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (ui->table->item(i, COL_ACTIVE_COUNT)->data(Qt::DisplayRole).toInt() == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             ui->table->removeRow(i); | 
					
						
							|  |  |  |             m_settings.m_frequencies.removeAt(i); // table_cellChanged isn't called for removeRow
 | 
					
						
							|  |  |  |             m_settings.m_enabled.removeAt(i); | 
					
						
							|  |  |  |             m_settings.m_notes.removeAt(i); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     QList<QString> settingsKeys({ | 
					
						
							|  |  |  |         "frequencies", | 
					
						
							|  |  |  |         "enabled", | 
					
						
							|  |  |  |         "notes" | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     applySettings(settingsKeys); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | static QList<QTableWidgetItem*> takeRow(QTableWidget* table, int row) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<QTableWidgetItem*> rowItems; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int col = 0; col < table->columnCount(); col++) { | 
					
						
							|  |  |  |         rowItems.append(table->takeItem(row, col)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return rowItems; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void setRow(QTableWidget* table, int row, const QList<QTableWidgetItem*>& rowItems) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (int col = 0; col < rowItems.size(); col++) { | 
					
						
							|  |  |  |         table->setItem(row, col, rowItems.at(col)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_up_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<QTableWidgetItem*> items = ui->table->selectedItems(); | 
					
						
							|  |  |  |     for (auto item : items) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int row = ui->table->row(item); | 
					
						
							|  |  |  |         if (row > 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QList<QTableWidgetItem*> sourceItems = takeRow(ui->table, row); | 
					
						
							|  |  |  |             QList<QTableWidgetItem*> destItems = takeRow(ui->table, row - 1); | 
					
						
							|  |  |  |             setRow(ui->table, row - 1, sourceItems); | 
					
						
							|  |  |  |             setRow(ui->table, row, destItems); | 
					
						
							|  |  |  |             ui->table->setCurrentCell(row - 1, 0); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::on_down_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<QTableWidgetItem*> items = ui->table->selectedItems(); | 
					
						
							|  |  |  |     for (auto item : items) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int row = ui->table->row(item); | 
					
						
							|  |  |  |         if (row < ui->table->rowCount() - 1) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QList<QTableWidgetItem*> sourceItems = takeRow(ui->table, row); | 
					
						
							|  |  |  |             QList<QTableWidgetItem*> destItems = takeRow(ui->table, row + 1); | 
					
						
							|  |  |  |             setRow(ui->table, row + 1, sourceItems); | 
					
						
							|  |  |  |             setRow(ui->table, row, destItems); | 
					
						
							|  |  |  |             ui->table->setCurrentCell(row + 1, 0); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-29 13:35:52 +00:00
										 |  |  | void FreqScannerGUI::on_clearActiveCount_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (int i = 0; i < ui->table->rowCount(); i++) { | 
					
						
							|  |  |  |         ui->table->item(i, COL_ACTIVE_COUNT)->setData(Qt::DisplayRole, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | void FreqScannerGUI::on_table_cellChanged(int row, int column) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QTableWidgetItem* item = ui->table->item(row, column); | 
					
						
							|  |  |  |     if (item) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (column == COL_FREQUENCY) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qint64 value = item->text().toLongLong(); | 
					
						
							|  |  |  |             while (m_settings.m_frequencies.size() <= row) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 m_settings.m_frequencies.append(0); | 
					
						
							|  |  |  |                 m_settings.m_enabled.append(true); | 
					
						
							|  |  |  |                 m_settings.m_notes.append(""); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             m_settings.m_frequencies[row] = value; | 
					
						
							|  |  |  |             updateAnnotation(row); | 
					
						
							|  |  |  |             QList<QString> settingsKeys({ | 
					
						
							|  |  |  |                  "frequencies", | 
					
						
							|  |  |  |                  "enabled", | 
					
						
							|  |  |  |                  "notes" | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             applySettings(settingsKeys); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (column == COL_ENABLE) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_settings.m_enabled[row] = item->checkState() == Qt::Checked; | 
					
						
							|  |  |  |             applySetting("enabled"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (column == COL_NOTES) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_settings.m_notes[row] = item->text(); | 
					
						
							|  |  |  |             applySetting("notes"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::updateAnnotation(int row) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QTableWidgetItem* item = ui->table->item(row, COL_FREQUENCY); | 
					
						
							|  |  |  |     QTableWidgetItem* annotationItem = ui->table->item(row, COL_ANNOTATION); | 
					
						
							|  |  |  |     if (item && annotationItem) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qint64 frequency = item->text().toLongLong(); | 
					
						
							|  |  |  |         const QList<SpectrumAnnotationMarker>& markers = m_deviceUISet->m_spectrum->getAnnotationMarkers(); | 
					
						
							|  |  |  |         const SpectrumAnnotationMarker* closest = nullptr; | 
					
						
							|  |  |  |         for (const auto& marker : markers) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if ((marker.m_startFrequency <= frequency) && (frequency < marker.m_startFrequency + marker.m_bandwidth)) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2023-09-28 18:02:58 +00:00
										 |  |  |                 if (marker.m_bandwidth == (unsigned)m_settings.m_channelBandwidth) { | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |                     // Exact match
 | 
					
						
							|  |  |  |                     annotationItem->setText(marker.m_text); | 
					
						
							|  |  |  |                     return; | 
					
						
							| 
									
										
										
										
											2023-10-03 15:09:54 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 else if (!closest) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |                     closest = ▮ | 
					
						
							| 
									
										
										
										
											2023-10-03 15:09:54 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |                     if (marker.m_bandwidth < closest->m_bandwidth) { | 
					
						
							|  |  |  |                         closest = ▮ | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (closest) { | 
					
						
							|  |  |  |             annotationItem->setText(closest->m_text); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-03 15:09:54 +00:00
										 |  |  | void FreqScannerGUI::updateAnnotations() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (int i = 0; i < ui->table->rowCount(); i++) { | 
					
						
							|  |  |  |         updateAnnotation(i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | void FreqScannerGUI::table_customContextMenuRequested(QPoint pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QTableWidgetItem* item = ui->table->itemAt(pos); | 
					
						
							|  |  |  |     if (item) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int row = item->row(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QMenu* tableContextMenu = new QMenu(ui->table); | 
					
						
							|  |  |  |         connect(tableContextMenu, &QMenu::aboutToHide, tableContextMenu, &QMenu::deleteLater); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Copy current cell
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QAction* copyAction = new QAction("Copy", tableContextMenu); | 
					
						
							|  |  |  |         const QString text = item->text(); | 
					
						
							|  |  |  |         connect(copyAction, &QAction::triggered, this, [text]()->void { | 
					
						
							|  |  |  |             QClipboard* clipboard = QGuiApplication::clipboard(); | 
					
						
							|  |  |  |             clipboard->setText(text); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         tableContextMenu->addAction(copyAction); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-02 14:45:17 +00:00
										 |  |  |         // Remove selected rows
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QAction* removeAction = new QAction("Remove", tableContextMenu); | 
					
						
							|  |  |  |         connect(removeAction, &QAction::triggered, this, [this]()->void { | 
					
						
							|  |  |  |             on_remove_clicked(); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |         tableContextMenu->addAction(removeAction); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |         tableContextMenu->addSeparator(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Tune to frequency
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const QRegExp re("R([0-9]+):([0-9]+)"); | 
					
						
							|  |  |  |         if (re.indexIn(m_settings.m_channel) >= 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             int scanDeviceSetIndex = re.capturedTexts()[1].toInt(); | 
					
						
							|  |  |  |             int scanChannelIndex = re.capturedTexts()[2].toInt(); | 
					
						
							|  |  |  |             qDebug() << "scanDeviceSetIndex" << scanDeviceSetIndex << "scanChannelIndex" << scanChannelIndex; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             qint64 frequency = ui->table->item(row, COL_FREQUENCY)->text().toLongLong(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QAction* findChannelMapAction = new QAction(QString("Tune R%1:%2 to %3").arg(scanDeviceSetIndex).arg(scanChannelIndex).arg(frequency), tableContextMenu); | 
					
						
							|  |  |  |             connect(findChannelMapAction, &QAction::triggered, this, [this, scanDeviceSetIndex, scanChannelIndex, frequency]()->void { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if ((frequency - m_settings.m_channelBandwidth / 2 < m_deviceCenterFrequency - m_basebandSampleRate / 2) | 
					
						
							|  |  |  |                     || (frequency + m_settings.m_channelBandwidth / 2 >= m_deviceCenterFrequency + m_basebandSampleRate / 2)) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     qint64 centerFrequency = frequency; | 
					
						
							|  |  |  |                     int offset = 0; | 
					
						
							|  |  |  |                     while (frequency - centerFrequency < m_settings.m_channelFrequencyOffset) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         centerFrequency -= m_settings.m_channelBandwidth; | 
					
						
							|  |  |  |                         offset += m_settings.m_channelBandwidth; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (!ChannelWebAPIUtils::setCenterFrequency(getDeviceSetIndex(), centerFrequency)) { | 
					
						
							|  |  |  |                         qWarning() << "Scanner failed to set frequency" << centerFrequency; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     ChannelWebAPIUtils::setFrequencyOffset(scanDeviceSetIndex, scanChannelIndex, offset); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     int offset = frequency - m_deviceCenterFrequency; | 
					
						
							|  |  |  |                     ChannelWebAPIUtils::setFrequencyOffset(scanDeviceSetIndex, scanChannelIndex, offset); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |             tableContextMenu->addAction(findChannelMapAction); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug() << "Failed to parse channel" << m_settings.m_channel; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tableContextMenu->popup(ui->table->viewport()->mapToGlobal(pos)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Columns in table reordered
 | 
					
						
							|  |  |  | void FreqScannerGUI::table_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void)oldVisualIndex; | 
					
						
							|  |  |  |     m_settings.m_columnIndexes[logicalIndex] = newVisualIndex; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Column in table resized (when hidden size is 0)
 | 
					
						
							|  |  |  | void FreqScannerGUI::table_sectionResized(int logicalIndex, int oldSize, int newSize) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void)oldSize; | 
					
						
							|  |  |  |     m_settings.m_columnSizes[logicalIndex] = newSize; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Right click in ADSB table header - show column select menu
 | 
					
						
							|  |  |  | void FreqScannerGUI::columnSelectMenu(QPoint pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_menu->popup(ui->table->horizontalHeader()->viewport()->mapToGlobal(pos)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Hide/show column when menu selected
 | 
					
						
							|  |  |  | void FreqScannerGUI::columnSelectMenuChecked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void)checked; | 
					
						
							|  |  |  |     QAction* action = qobject_cast<QAction*>(sender()); | 
					
						
							|  |  |  |     if (action != nullptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int idx = action->data().toInt(nullptr); | 
					
						
							|  |  |  |         ui->table->setColumnHidden(idx, !action->isChecked()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create column select menu item
 | 
					
						
							|  |  |  | QAction* FreqScannerGUI::createCheckableItem(QString& text, int idx, bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QAction* action = new QAction(text, this); | 
					
						
							|  |  |  |     action->setCheckable(true); | 
					
						
							|  |  |  |     action->setChecked(checked); | 
					
						
							|  |  |  |     action->setData(QVariant(idx)); | 
					
						
							|  |  |  |     connect(action, SIGNAL(triggered()), this, SLOT(columnSelectMenuChecked())); | 
					
						
							|  |  |  |     return action; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::resizeTable() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Fill table with a row of dummy data that will size the columns nicely
 | 
					
						
							|  |  |  |     int row = ui->table->rowCount(); | 
					
						
							|  |  |  |     ui->table->setRowCount(row + 1); | 
					
						
							| 
									
										
										
										
											2023-10-02 14:45:17 +00:00
										 |  |  |     ui->table->setItem(row, COL_FREQUENCY, new QTableWidgetItem("800,000.5 MHz")); | 
					
						
							| 
									
										
										
										
											2023-10-03 15:09:54 +00:00
										 |  |  |     ui->table->setItem(row, COL_ANNOTATION, new QTableWidgetItem("London VOLMET")); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |     ui->table->setItem(row, COL_ENABLE, new QTableWidgetItem("Enable")); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_POWER, new QTableWidgetItem("-100.0")); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_ACTIVE_COUNT, new QTableWidgetItem("10000")); | 
					
						
							|  |  |  |     ui->table->setItem(row, COL_NOTES, new QTableWidgetItem("Enter some notes")); | 
					
						
							|  |  |  |     ui->table->resizeColumnsToContents(); | 
					
						
							|  |  |  |     ui->table->setRowCount(row); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::makeUIConnections() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QObject::connect(ui->channels, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_channels_currentIndexChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &FreqScannerGUI::on_deltaFrequency_changed); | 
					
						
							|  |  |  |     QObject::connect(ui->channelBandwidth, &ValueDialZ::changed, this, &FreqScannerGUI::on_channelBandwidth_changed); | 
					
						
							|  |  |  |     QObject::connect(ui->scanTime, &QDial::valueChanged, this, &FreqScannerGUI::on_scanTime_valueChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->retransmitTime, &QDial::valueChanged, this, &FreqScannerGUI::on_retransmitTime_valueChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->tuneTime, &QDial::valueChanged, this, &FreqScannerGUI::on_tuneTime_valueChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->thresh, &QDial::valueChanged, this, &FreqScannerGUI::on_thresh_valueChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->priority, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_priority_currentIndexChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->measurement, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_measurement_currentIndexChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_mode_currentIndexChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->startStop, &ButtonSwitch::clicked, this, &FreqScannerGUI::on_startStop_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->table, &QTableWidget::cellChanged, this, &FreqScannerGUI::on_table_cellChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->addSingle, &QToolButton::clicked, this, &FreqScannerGUI::on_addSingle_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->addRange, &QToolButton::clicked, this, &FreqScannerGUI::on_addRange_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->remove, &QToolButton::clicked, this, &FreqScannerGUI::on_remove_clicked); | 
					
						
							| 
									
										
										
										
											2023-10-02 14:45:17 +00:00
										 |  |  |     QObject::connect(ui->removeInactive, &QToolButton::clicked, this, &FreqScannerGUI::on_removeInactive_clicked); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  |     QObject::connect(ui->up, &QToolButton::clicked, this, &FreqScannerGUI::on_up_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->down, &QToolButton::clicked, this, &FreqScannerGUI::on_down_clicked); | 
					
						
							| 
									
										
										
										
											2023-09-29 13:35:52 +00:00
										 |  |  |     QObject::connect(ui->clearActiveCount, &QToolButton::clicked, this, &FreqScannerGUI::on_clearActiveCount_clicked); | 
					
						
							| 
									
										
										
										
											2023-09-28 15:45:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FreqScannerGUI::updateAbsoluteCenterFrequency() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setStatusFrequency(m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset); | 
					
						
							|  |  |  | } |