Add Add Channels dialog, to easily add Channel Powe channels.

This commit is contained in:
srcejon 2024-04-06 22:17:56 +01:00
parent 116d6674bd
commit be7199531d
10 changed files with 357 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -27,12 +27,15 @@ if(NOT SERVER_MODE)
sidgui.ui
sidsettingsdialog.cpp
sidsettingsdialog.ui
sidaddchannelsdialog.cpp
sidaddchannelsdialog.ui
icons.qrc
)
set(sid_HEADERS
${sid_HEADERS}
sidgui.h
sidsettingsdialog.h
sidaddchannelsdialog.h
)
set(TARGET_NAME featuresid)

View File

@ -119,7 +119,17 @@ When checked, all data is displayed on a single combined chart.
Check to display a legend on the chart. When unchecked the legend will be hidden. You can click on items in the legend to temporarily hide and then show the corresponding series on the chart.
The position of the legend can be set in the Settings Dialog.
<h3>16: Open Settings Dialog</h3>
<h3>16: Add Channels</h3>
Click to open the Add Channels Dialog. This allows you to easily add the Channel Power channels for each VLF transmitter on each RX device.
This dialog shows a table with one row for each VLF Transmitter, and a column for each RX device.
When OK is pressed, a corresponding Channel Power channel will be created for every cell that is checked.
For example, in the image below, Channel Power channels will be added for the GDQ transmitter on both devices R0 and R1, with one for FTA on device R0 only.
![SID Add Channels dialog](../../../doc/img/SID_plugin_addchannels.png)
<h3>17: Open Settings Dialog</h3>
Click to open the Settings Dialog. The settings dialog allows a user to:
@ -134,7 +144,7 @@ Click to open the Settings Dialog. The settings dialog allows a user to:
![SID settings dialog](../../../doc/img/SID_plugin_settings_dialog.png)
<h3>17: Display SDO/SOHO Imagery</h3>
<h3>18: Display SDO/SOHO Imagery</h3>
When checked, displays imagary from NASA's SDO (Solar Dynamic Observatory) and ESA/NASA's SOHO (Solar and Heliospheric Observatory) satellites.
@ -142,11 +152,11 @@ SDOs images the Sun in a variety of UV and EUV wavelengths. SOHO shows images of
Solar flares are particularly visible in the AIA 131 Å images.
<h3>18: Image or Video Selection</h3>
<h3>19: Image or Video Selection</h3>
Selects whether to display images (unchecked) or video (checked).
<h3>19: Image/Wavelength Selection</h3>
<h3>20: Image/Wavelength Selection</h3>
Selects which image / wavelength to view.
@ -172,63 +182,63 @@ Selects which image / wavelength to view.
* LASCO (Large Angle Spectrometric Coronagraph) shows solar corona. C2 shows corona up to 8.4Mkm. C3 shows corona up to 23Mkm.
<h3>20: Show GOES 16, 18 and SDO</h3>
<h3>21: Show GOES 16, 18 and SDO</h3>
When checked, opens a [Satellite Tracker](../../feature/satellitetracker/readme.md) feature and sets it to display data for the GOES 16, GOES 18 and SDO satellites.
The position and tracks of the satellites will then be visible on a [Map](../../feature/map/readme.md) feature.
<h3>21: Autoscale X</h3>
<h3>22: Autoscale X</h3>
When clicked, the chart X-axis is automatically scaled so that all power data is visible. When right-clicked, autoscaling of the X-axis will occur whenever new data is added to the chart.
<h3>22: Autoscale Y</h3>
<h3>23: Autoscale Y</h3>
When clicked, the chart Y-axis is automatically scaled so that all power data is visible. When right-clicked, autoscaling of the Y-axis will occur whenever new data is added to the chart.
<h3>23: Set X-axis to Today</h3>
<h3>24: Set X-axis to Today</h3>
When clicked, the X-axis is set to show today, from midnight to midnight.
When right-clicked, the X-axis is set to show sunrise to sunset. This uses latitude and longitude from Preferences > My position.
<h3>24: Set X-axis to -1 day</h3>
<h3>25: Set X-axis to -1 day</h3>
When clicked, the X-axis is set 1 day earlier than the current setting, at the same time.
<h3>25: Set X-axis to +1 day</h3>
<h3>26: Set X-axis to +1 day</h3>
When clicked, the X-axis is set 1 day later than the current setting, at the same time.
<h3>26: Start Time</h3>
<h3>27: Start Time</h3>
Displays/sets the current start time of the chart (X-axis minimum). It's possible to scroll through hours/days/months by clicking on the relevent segment and using the mouse scroll wheel.
<h3>27: End Time</h3>
<h3>28: End Time</h3>
Displays/sets the current end time of the chart (X-axis maximum). It's possible to scroll through hours/days/months by clicking on the relevent segment and using the mouse scroll wheel.
<h3>28: Min</h3>
<h3>29: Min</h3>
Displays/sets the minimum Y-axis value.
<h3>29: Max</h3>
<h3>30: Max</h3>
Displays/sets the maximum Y-axis value.
<h3>30: Now</h3>
<h3>31: Now</h3>
When checked, the latest SDO imagery is displayed. When unchecked, you can enter a date and time for which imagery should be displayed.
<h3>31: Date Time</h3>
<h3>32: Date Time</h3>
Specifies the date and time for which SDO imagery should be displayed. Images are updated every 15 minutes. The date and time can also be set by clicking on the chart.
<h3>32: Map</h3>
<h3>33: Map</h3>
Select a Map to link to the SID feature. When a time is selected on the SID charts, the [Map](../../feature/map/readme.md) feature will have it's time set accordingly.
This allows you, for example, to see the corresponding impact on MUF/foF2 displayed on the 3D map.
<h3>33: Show Paths on Map</h3>
<h3>34: Show Paths on Map</h3>
When clicked, shows the great circle paths between transmitters and receivers on a [Map](../../feature/map/readme.md).

View File

@ -0,0 +1,147 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2024 Jon Beniston, M7RCE //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// 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 <QTableWidgetItem>
#include <QDebug>
#include "util/vlftransmitters.h"
#include "channel/channelwebapiutils.h"
#include "device/deviceapi.h"
#include "device/deviceset.h"
#include "dsp/dspdevicesourceengine.h"
#include "maincore.h"
#include "sidaddchannelsdialog.h"
SIDAddChannelsDialog::SIDAddChannelsDialog(SIDSettings *settings, QWidget* parent) :
QDialog(parent),
ui(new Ui::SIDAddChannelsDialog),
m_settings(settings)
{
ui->setupUi(this);
MainCore *mainCore = MainCore::instance();
std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets();
ui->channels->setColumnCount(deviceSets.size() + 2);
// Create column header
ui->channels->setHorizontalHeaderItem(COL_TX_NAME, new QTableWidgetItem("Callsign"));
ui->channels->setHorizontalHeaderItem(COL_TX_FREQUENCY, new QTableWidgetItem("Frequency (Hz)"));
for (int i = 0; i < deviceSets.size(); i++)
{
if (deviceSets[i]->m_deviceSourceEngine || deviceSets[i]->m_deviceMIMOEngine)
{
QTableWidgetItem *item = new QTableWidgetItem(mainCore->getDeviceSetId(deviceSets[i]));
ui->channels->setHorizontalHeaderItem(COL_DEVICE + i, item);
}
}
// Add row for each transmitter, with checkbox for each device
for (int j = 0; j < VLFTransmitters::m_transmitters.size(); j++)
{
int row = ui->channels->rowCount();
ui->channels->setRowCount(row+1);
ui->channels->setItem(row, COL_TX_NAME, new QTableWidgetItem(VLFTransmitters::m_transmitters[j].m_callsign));
ui->channels->setItem(row, COL_TX_FREQUENCY, new QTableWidgetItem(QString::number(VLFTransmitters::m_transmitters[j].m_frequency)));
for (int i = 0; i < deviceSets.size(); i++)
{
if (deviceSets[i]->m_deviceSourceEngine || deviceSets[i]->m_deviceMIMOEngine)
{
QTableWidgetItem *enableItem = new QTableWidgetItem();
enableItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
enableItem->setCheckState(Qt::Unchecked);
ui->channels->setItem(row, COL_DEVICE + i, enableItem);
}
}
}
ui->channels->resizeColumnsToContents();
}
SIDAddChannelsDialog::~SIDAddChannelsDialog()
{
delete ui;
}
void SIDAddChannelsDialog::accept()
{
MainCore *mainCore = MainCore::instance();
connect(mainCore, &MainCore::channelAdded, this, &SIDAddChannelsDialog::channelAdded);
m_count = m_settings->m_channelSettings.size();
m_row = 0;
m_col = COL_DEVICE;
addNextChannel();
}
void SIDAddChannelsDialog::addNextChannel()
{
if (m_row < ui->channels->rowCount())
{
QString id = ui->channels->horizontalHeaderItem(m_col)->text();
unsigned int deviceSetIndex;
if (ui->channels->item(m_row, m_col)->checkState() == Qt::Checked)
{
MainCore::getDeviceSetIndexFromId(id, deviceSetIndex);
ChannelWebAPIUtils::addChannel(deviceSetIndex, "sdrangel.channel.channelpower", 0);
}
else
{
nextChannel(); // can recursively call this method
}
}
else
{
QDialog::accept();
}
}
void SIDAddChannelsDialog::nextChannel()
{
m_col++;
if (m_col >= ui->channels->columnCount())
{
m_col = COL_DEVICE;
m_row++;
}
addNextChannel();
}
void SIDAddChannelsDialog::channelAdded(int deviceSetIndex, ChannelAPI *channel)
{
const VLFTransmitters::Transmitter *transmitter = VLFTransmitters::m_callsignHash.value(ui->channels->item(m_row, COL_TX_NAME)->text());
ChannelWebAPIUtils::patchChannelSetting(channel, "title", transmitter->m_callsign);
ChannelWebAPIUtils::patchChannelSetting(channel, "frequency", transmitter->m_frequency);
ChannelWebAPIUtils::patchChannelSetting(channel, "frequencyMode", 1);
ChannelWebAPIUtils::patchChannelSetting(channel, "rfBandwidth", 300);
ChannelWebAPIUtils::patchChannelSetting(channel, "averagePeriodUS", 10000000);
// Update setings if they are created by SIDGUI before this slot is called
if (m_count < m_settings->m_channelSettings.size()) {
m_settings->m_channelSettings[m_count].m_label = transmitter->m_callsign;
}
m_count++;
nextChannel();
}

View File

@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2024 Jon Beniston, M7RCE //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_SIDADDCHANNELSDIALOG_H
#define INCLUDE_SIDADDCHANNELSDIALOG_H
#include "ui_sidaddchannelsdialog.h"
#include "sidsettings.h"
class SIDAddChannelsDialog : public QDialog {
Q_OBJECT
public:
explicit SIDAddChannelsDialog(SIDSettings *settings, QWidget* parent = 0);
~SIDAddChannelsDialog();
private:
private slots:
void accept();
void channelAdded(int deviceSetIndex, ChannelAPI *channel);
private:
Ui::SIDAddChannelsDialog* ui;
enum Column {
COL_TX_NAME,
COL_TX_FREQUENCY,
COL_DEVICE
};
SIDSettings *m_settings;
int m_row; // Row and column in table, when adding channels
int m_col;
int m_count; // How many channels we've added
void addNextChannel();
void nextChannel();
};
#endif // INCLUDE_SIDADDCHANNELSDIALOG_H

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SIDAddChannelsDialog</class>
<widget class="QDialog" name="SIDAddChannelsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>441</width>
<height>463</height>
</rect>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Add channels</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Select devices and VLF transmitters to add channels for</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QTableWidget" name="channels">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="verticalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SIDAddChannelsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SIDAddChannelsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -39,6 +39,7 @@
#include "sid.h"
#include "sidgui.h"
#include "sidsettingsdialog.h"
#include "sidaddchannelsdialog.h"
#include "SWGMapItem.h"
@ -1482,6 +1483,16 @@ void SIDGUI::on_deleteAll_clicked()
getData();
}
void SIDGUI::on_addChannels_clicked()
{
SIDAddChannelsDialog dialog(&m_settings);
new DialogPositioner(&dialog, true);
dialog.exec();
}
void SIDGUI::on_settings_clicked()
{
SIDSettingsDialog dialog(&m_settings);
@ -1493,6 +1504,8 @@ void SIDGUI::on_settings_clicked()
&SIDGUI::removeChannels
);
new DialogPositioner(&dialog, true);
if (dialog.exec() == QDialog::Accepted)
{
setAutosaveTimer();
@ -1587,6 +1600,7 @@ void SIDGUI::makeUIConnections()
QObject::connect(ui->saveData, &QToolButton::clicked, this, &SIDGUI::on_saveData_clicked);
QObject::connect(ui->loadData, &QToolButton::clicked, this, &SIDGUI::on_loadData_clicked);
QObject::connect(ui->saveChartImage, &QToolButton::clicked, this, &SIDGUI::on_saveChartImage_clicked);
QObject::connect(ui->addChannels, &QToolButton::clicked, this, &SIDGUI::on_addChannels_clicked);
QObject::connect(ui->settings, &QToolButton::clicked, this, &SIDGUI::on_settings_clicked);
}

View File

@ -284,6 +284,7 @@ private slots:
void updateStatus();
void autosave();
void on_settings_clicked();
void on_addChannels_clicked();
void xRayDataUpdated(const QList<GOESXRay::XRayData>& data, bool primary);
void protonDataUpdated(const QList<GOESXRay::ProtonData>& data, bool primary);
void grbDataUpdated(const QList<GRB::Data>& data);

View File

@ -327,6 +327,20 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="addChannels">
<property name="toolTip">
<string>Add channels</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/channels_add.png</normaloff>:/channels_add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="settings">
<property name="toolTip">