| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2016 Edouard Griffiths, F4EXB                                   //
 | 
					
						
							|  |  |  | // Copyright (C) 2020 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 <limits>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QDockWidget>
 | 
					
						
							|  |  |  | #include <QMainWindow>
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include <QQuickItem>
 | 
					
						
							|  |  |  | #include <QGeoLocation>
 | 
					
						
							|  |  |  | #include <QGeoCoordinate>
 | 
					
						
							|  |  |  | #include <QQmlContext>
 | 
					
						
							| 
									
										
										
										
											2022-09-30 15:59:51 +01:00
										 |  |  | #include <QQmlProperty>
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | #include <QMessageBox>
 | 
					
						
							|  |  |  | #include <QAction>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "feature/featureuiset.h"
 | 
					
						
							|  |  |  | #include "dsp/dspengine.h"
 | 
					
						
							|  |  |  | #include "dsp/dspcommands.h"
 | 
					
						
							|  |  |  | #include "dsp/dspengine.h"
 | 
					
						
							|  |  |  | #include "ui_vorlocalizergui.h"
 | 
					
						
							|  |  |  | #include "plugin/pluginapi.h"
 | 
					
						
							|  |  |  | #include "util/simpleserializer.h"
 | 
					
						
							|  |  |  | #include "util/db.h"
 | 
					
						
							|  |  |  | #include "util/morse.h"
 | 
					
						
							|  |  |  | #include "util/units.h"
 | 
					
						
							|  |  |  | #include "gui/basicfeaturesettingsdialog.h"
 | 
					
						
							|  |  |  | #include "gui/crightclickenabler.h"
 | 
					
						
							|  |  |  | #include "maincore.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "vorlocalizer.h"
 | 
					
						
							|  |  |  | #include "vorlocalizerreport.h"
 | 
					
						
							|  |  |  | #include "vorlocalizersettings.h"
 | 
					
						
							|  |  |  | #include "vorlocalizergui.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Lats and longs in decimal degrees. Distance in metres. Bearing in degrees.
 | 
					
						
							|  |  |  | // https://www.movable-type.co.uk/scripts/latlong.html
 | 
					
						
							|  |  |  | static void calcRadialEndPoint(float startLatitude, float startLongitude, float distance, float bearing, float &endLatitude, float &endLongitude) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     double startLatRad = startLatitude*M_PI/180.0; | 
					
						
							|  |  |  |     double startLongRad = startLongitude*M_PI/180.0; | 
					
						
							|  |  |  |     double theta = bearing*M_PI/180.0; | 
					
						
							|  |  |  |     double earthRadius = 6378137.0; // At equator
 | 
					
						
							|  |  |  |     double delta = distance/earthRadius; | 
					
						
							|  |  |  |     double endLatRad = std::asin(sin(startLatRad)*cos(delta) + cos(startLatRad)*sin(delta)*cos(theta)); | 
					
						
							|  |  |  |     double endLongRad = startLongRad + std::atan2(sin(theta)*sin(delta)*cos(startLatRad), cos(delta) - sin(startLatRad)*sin(endLatRad)); | 
					
						
							|  |  |  |     endLatitude = endLatRad*180.0/M_PI; | 
					
						
							|  |  |  |     endLongitude = endLongRad*180.0/M_PI; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Calculate intersection point along two radials
 | 
					
						
							|  |  |  | // https://www.movable-type.co.uk/scripts/latlong.html
 | 
					
						
							|  |  |  | static bool calcIntersectionPoint(float lat1, float lon1, float bearing1, float lat2, float lon2, float bearing2, float &intersectLat, float &intersectLon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     double lat1Rad = Units::degreesToRadians(lat1); | 
					
						
							|  |  |  |     double lon1Rad = Units::degreesToRadians(lon1); | 
					
						
							|  |  |  |     double lat2Rad = Units::degreesToRadians(lat2); | 
					
						
							|  |  |  |     double lon2Rad = Units::degreesToRadians(lon2); | 
					
						
							|  |  |  |     double theta13 = Units::degreesToRadians(bearing1); | 
					
						
							|  |  |  |     double theta23 = Units::degreesToRadians(bearing2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     double deltaLat = lat1Rad - lat2Rad; | 
					
						
							|  |  |  |     double deltaLon = lon1Rad - lon2Rad; | 
					
						
							|  |  |  |     double sindlat = sin(deltaLat/2.0); | 
					
						
							|  |  |  |     double sindlon = sin(deltaLon/2.0); | 
					
						
							|  |  |  |     double cosLat1 = cos(lat1Rad); | 
					
						
							|  |  |  |     double cosLat2 = cos(lat2Rad); | 
					
						
							|  |  |  |     double delta12 = 2.0 * asin(sqrt(sindlat*sindlat+cosLat1*cosLat2*sindlon*sindlon)); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (abs(delta12) < std::numeric_limits<float>::epsilon()) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     double sinLat1 = sin(lat1Rad); | 
					
						
							|  |  |  |     double sinLat2 = sin(lat2Rad); | 
					
						
							|  |  |  |     double sinDelta12 = sin(delta12); | 
					
						
							|  |  |  |     double cosDelta12 = cos(delta12); | 
					
						
							|  |  |  |     double thetaA = acos((sinLat2-sinLat1*cosDelta12)/(sinDelta12*cosLat1)); | 
					
						
							|  |  |  |     double thetaB = acos((sinLat1-sinLat2*cosDelta12)/(sinDelta12*cosLat2)); | 
					
						
							|  |  |  |     double theta12, theta21; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     if (sin(lon2Rad-lon1Rad) > 0.0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         theta12 = thetaA; | 
					
						
							|  |  |  |         theta21 = 2.0*M_PI-thetaB; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         theta12 = 2.0*M_PI-thetaA; | 
					
						
							|  |  |  |         theta21 = thetaB; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     double alpha1 = theta13 - theta12; | 
					
						
							|  |  |  |     double alpha2 = theta21 - theta23; | 
					
						
							|  |  |  |     double sinAlpha1 = sin(alpha1); | 
					
						
							|  |  |  |     double sinAlpha2 = sin(alpha2); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((sinAlpha1 == 0.0) && (sinAlpha2 == 0.0)) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (sinAlpha1*sinAlpha2 < 0.0) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     double cosAlpha1 = cos(alpha1); | 
					
						
							|  |  |  |     double cosAlpha2 = cos(alpha2); | 
					
						
							|  |  |  |     double cosAlpha3 = -cosAlpha1*cosAlpha2+sinAlpha1*sinAlpha2*cos(delta12); | 
					
						
							|  |  |  |     double delta13 = atan2(sin(delta12)*sinAlpha1*sinAlpha2, cosAlpha2+cosAlpha1*cosAlpha3); | 
					
						
							|  |  |  |     double lat3Rad = asin(sinLat1*cos(delta13)+cosLat1*sin(delta13)*cos(theta13)); | 
					
						
							|  |  |  |     double lon3Rad = lon1Rad + atan2(sin(theta13)*sin(delta13)*cosLat1, cos(delta13)-sinLat1*sin(lat3Rad)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 17:10:18 +00:00
										 |  |  |     intersectLat = Units::radiansToDegrees(lat3Rad); | 
					
						
							|  |  |  |     intersectLon = Units::radiansToDegrees(lon3Rad); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | VORGUI::VORGUI(NavAid *navAid, VORLocalizerGUI *gui) : | 
					
						
							|  |  |  |     m_navAid(navAid), | 
					
						
							|  |  |  |     m_gui(gui) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // These are deleted by QTableWidget
 | 
					
						
							|  |  |  |     m_nameItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_frequencyItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_radialItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_identItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_morseItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_rxIdentItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_rxMorseItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_varMagItem = new QTableWidgetItem(); | 
					
						
							|  |  |  |     m_refMagItem = new QTableWidgetItem(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_muteItem = new QWidget(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_muteButton = new QToolButton(); | 
					
						
							|  |  |  |     m_muteButton->setCheckable(true); | 
					
						
							|  |  |  |     m_muteButton->setChecked(false); | 
					
						
							|  |  |  |     m_muteButton->setToolTip("Mute/unmute audio from this VOR"); | 
					
						
							|  |  |  |     m_muteButton->setIcon(m_gui->m_muteIcon); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QHBoxLayout* pLayout = new QHBoxLayout(m_muteItem); | 
					
						
							|  |  |  |     pLayout->addWidget(m_muteButton); | 
					
						
							|  |  |  |     pLayout->setAlignment(Qt::AlignCenter); | 
					
						
							|  |  |  |     pLayout->setContentsMargins(0, 0, 0, 0); | 
					
						
							|  |  |  |     m_muteItem->setLayout(pLayout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(m_muteButton, &QPushButton::toggled, this, &VORGUI::on_audioMute_toggled); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_coordinates.push_back(QVariant::fromValue(*new QGeoCoordinate(m_navAid->m_latitude, m_navAid->m_longitude, Units::feetToMetres(m_navAid->m_elevation)))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORGUI::on_audioMute_toggled(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     m_gui->m_settings.m_subChannelSettings[m_navAid->m_id].m_audioMute = checked; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     m_gui->applySettings(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QVariant VORModel::data(const QModelIndex &index, int role) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int row = index.row(); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((row < 0) || (row >= m_vors.count())) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return QVariant(); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     if (role == VORModel::positionRole) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Coordinates to display the VOR icon at
 | 
					
						
							|  |  |  |         QGeoCoordinate coords; | 
					
						
							|  |  |  |         coords.setLatitude(m_vors[row]->m_latitude); | 
					
						
							|  |  |  |         coords.setLongitude(m_vors[row]->m_longitude); | 
					
						
							|  |  |  |         coords.setAltitude(Units::feetToMetres(m_vors[row]->m_elevation)); | 
					
						
							|  |  |  |         return QVariant::fromValue(coords); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (role == VORModel::vorDataRole) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Create the text to go in the bubble next to the VOR
 | 
					
						
							|  |  |  |         QStringList list; | 
					
						
							|  |  |  |         list.append(QString("Name: %1").arg(m_vors[row]->m_name)); | 
					
						
							|  |  |  |         list.append(QString("Frequency: %1 MHz").arg(m_vors[row]->m_frequencykHz / 1000.0f, 0, 'f', 1)); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (m_vors[row]->m_channel != "") { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             list.append(QString("Channel: %1").arg(m_vors[row]->m_channel)); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         list.append(QString("Ident: %1 %2").arg(m_vors[row]->m_ident).arg(Morse::toSpacedUnicodeMorse(m_vors[row]->m_ident))); | 
					
						
							|  |  |  |         list.append(QString("Range: %1 nm").arg(m_vors[row]->m_range)); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (m_vors[row]->m_alignedTrueNorth) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             list.append(QString("Magnetic declination: Aligned to true North")); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         } else if (m_vors[row]->m_magneticDeclination != 0.0f) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             list.append(QString("Magnetic declination: %1%2").arg(std::round(m_vors[row]->m_magneticDeclination)).arg(QChar(0x00b0))); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         QString data = list.join("\n"); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return QVariant::fromValue(data); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (role == VORModel::vorImageRole) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Select an image to use for the VOR
 | 
					
						
							|  |  |  |         return QVariant::fromValue(QString("/demodvor/map/%1.png").arg(m_vors[row]->m_type)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (role == VORModel::bubbleColourRole) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Select a background colour for the text bubble next to the VOR
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         if (m_selected[row]) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             return QVariant::fromValue(QColor("lightgreen")); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             return QVariant::fromValue(QColor("lightblue")); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (role == VORModel::vorRadialRole) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        // Draw a radial line from centre of VOR outwards at the demodulated angle
 | 
					
						
							|  |  |  |        if (m_radialsVisible && m_selected[row] && (m_vorGUIs[row] != nullptr) && (m_radials[row] != -1.0f)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |            QVariantList list; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            list.push_back(m_vorGUIs[row]->m_coordinates[0]); // Centre of VOR
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            float endLat, endLong; | 
					
						
							|  |  |  |            float bearing; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |            if (m_gui->m_settings.m_magDecAdjust && !m_vors[row]->m_alignedTrueNorth) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                bearing = m_radials[row] - m_vors[row]->m_magneticDeclination; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |            } else { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                bearing = m_radials[row]; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |            } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |            calcRadialEndPoint(m_vors[row]->m_latitude, m_vors[row]->m_longitude, m_vors[row]->getRangeMetres(), bearing, endLat, endLong); | 
					
						
							|  |  |  |            list.push_back(QVariant::fromValue(*new QGeoCoordinate(endLat, endLong, Units::feetToMetres(m_vors[row]->m_elevation)))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            return list; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        else | 
					
						
							|  |  |  |            return QVariantList(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (role == VORModel::selectedRole) | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return QVariant::fromValue(m_selected[row]); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     return QVariant(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool VORModel::setData(const QModelIndex &index, const QVariant& value, int role) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int row = index.row(); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((row < 0) || (row >= m_vors.count())) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     if (role == VORModel::selectedRole) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         bool selected = value.toBool(); | 
					
						
							|  |  |  |         VORGUI *vorGUI; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (selected) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         { | 
					
						
							|  |  |  |             vorGUI = new VORGUI(m_vors[row], m_gui); | 
					
						
							|  |  |  |             m_vorGUIs[row] = vorGUI; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             vorGUI = m_vorGUIs[row]; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         m_gui->selectVOR(vorGUI, selected); | 
					
						
							|  |  |  |         m_selected[row] = selected; | 
					
						
							|  |  |  |         emit dataChanged(index, index); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         if (!selected) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             delete vorGUI; | 
					
						
							|  |  |  |             m_vorGUIs[row] = nullptr; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Find intersection between first two selected radials
 | 
					
						
							|  |  |  | bool VORModel::findIntersection(float &lat, float &lon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_vors.count() > 2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         float lat1, lon1, bearing1, valid1 = false; | 
					
						
							|  |  |  |         float lat2, lon2, bearing2, valid2 = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (int i = 0; i < m_vors.count(); i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (m_selected[i] && (m_radials[i] >= 0.0)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!valid1) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     lat1 = m_vors[i]->m_latitude; | 
					
						
							|  |  |  |                     lon1 = m_vors[i]->m_longitude; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     if (m_gui->m_settings.m_magDecAdjust && !m_vors[i]->m_alignedTrueNorth) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                         bearing1 = m_radials[i] - m_vors[i]->m_magneticDeclination; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |                     } else { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                         bearing1 = m_radials[i]; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                     valid1 = true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     lat2 = m_vors[i]->m_latitude; | 
					
						
							|  |  |  |                     lon2 = m_vors[i]->m_longitude; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     if (m_gui->m_settings.m_magDecAdjust && !m_vors[i]->m_alignedTrueNorth) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                         bearing2 = m_radials[i] - m_vors[i]->m_magneticDeclination; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |                     } else { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                         bearing2 = m_radials[i]; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |                     valid2 = true; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         if (valid1 && valid2) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             return calcIntersectionPoint(lat1, lon1, bearing1, lat2, lon2, bearing2, lat, lon); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::resizeTable() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Fill table with a row of dummy data that will size the columns nicely
 | 
					
						
							|  |  |  |     // Trailing spaces are for sort arrow
 | 
					
						
							|  |  |  |     QString morse("---- ---- ----"); | 
					
						
							|  |  |  |     int row = ui->vorData->rowCount(); | 
					
						
							|  |  |  |     ui->vorData->setRowCount(row + 1); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_NAME, new QTableWidgetItem("White Sulphur Springs")); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_FREQUENCY, new QTableWidgetItem("Freq (MHz) ")); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_IDENT, new QTableWidgetItem("Ident ")); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_MORSE, new QTableWidgetItem(Morse::toSpacedUnicode(morse))); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_RADIAL, new QTableWidgetItem("Radial (o) ")); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_RX_IDENT, new QTableWidgetItem("RX Ident ")); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_RX_MORSE, new QTableWidgetItem(Morse::toSpacedUnicode(morse))); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_VAR_MAG, new QTableWidgetItem("Var (dB) ")); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_REF_MAG, new QTableWidgetItem("Ref (dB) ")); | 
					
						
							|  |  |  |     ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_MUTE, new QTableWidgetItem("Mute")); | 
					
						
							|  |  |  |     ui->vorData->resizeColumnsToContents(); | 
					
						
							|  |  |  |     ui->vorData->removeRow(row); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Columns in table reordered
 | 
					
						
							|  |  |  | void VORLocalizerGUI::vorData_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 VORLocalizerGUI::vorData_sectionResized(int logicalIndex, int oldSize, int newSize) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) oldSize; | 
					
						
							|  |  |  |     m_settings.m_columnSizes[logicalIndex] = newSize; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Right click in table header - show column select menu
 | 
					
						
							|  |  |  | void VORLocalizerGUI::columnSelectMenu(QPoint pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     menu->popup(ui->vorData->horizontalHeader()->viewport()->mapToGlobal(pos)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Hide/show column when menu selected
 | 
					
						
							|  |  |  | void VORLocalizerGUI::columnSelectMenuChecked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) checked; | 
					
						
							|  |  |  |     QAction* action = qobject_cast<QAction*>(sender()); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (action) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         int idx = action->data().toInt(nullptr); | 
					
						
							|  |  |  |         ui->vorData->setColumnHidden(idx, !action->isChecked()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create column select menu item
 | 
					
						
							|  |  |  | QAction *VORLocalizerGUI::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())); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     return action; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Called when a VOR is selected on the map
 | 
					
						
							|  |  |  | void VORLocalizerGUI::selectVOR(VORGUI *vorGUI, bool selected) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int navId = vorGUI->m_navAid->m_id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (selected) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizer::MsgAddVORChannel *msg = VORLocalizer::MsgAddVORChannel::create(navId); | 
					
						
							|  |  |  |         m_vorLocalizer->getInputMessageQueue()->push(msg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_selectedVORs.insert(navId, vorGUI); | 
					
						
							|  |  |  |         ui->vorData->setSortingEnabled(false); | 
					
						
							|  |  |  |         int row = ui->vorData->rowCount(); | 
					
						
							|  |  |  |         ui->vorData->setRowCount(row + 1); | 
					
						
							|  |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_NAME, vorGUI->m_nameItem); | 
					
						
							|  |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_FREQUENCY, vorGUI->m_frequencyItem); | 
					
						
							| 
									
										
										
										
											2022-05-04 09:08:31 +01:00
										 |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_IDENT, vorGUI->m_identItem); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_MORSE, vorGUI->m_morseItem); | 
					
						
							|  |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_RADIAL, vorGUI->m_radialItem); | 
					
						
							|  |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_RX_IDENT, vorGUI->m_rxIdentItem); | 
					
						
							|  |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_RX_MORSE, vorGUI->m_rxMorseItem); | 
					
						
							|  |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_VAR_MAG, vorGUI->m_varMagItem); | 
					
						
							|  |  |  |         ui->vorData->setItem(row, VORLocalizerSettings::VOR_COL_REF_MAG, vorGUI->m_refMagItem); | 
					
						
							|  |  |  |         ui->vorData->setCellWidget(row, VORLocalizerSettings::VOR_COL_MUTE, vorGUI->m_muteItem); | 
					
						
							|  |  |  |         vorGUI->m_nameItem->setText(vorGUI->m_navAid->m_name); | 
					
						
							|  |  |  |         vorGUI->m_identItem->setText(vorGUI->m_navAid->m_ident); | 
					
						
							|  |  |  |         vorGUI->m_morseItem->setText(Morse::toSpacedUnicodeMorse(vorGUI->m_navAid->m_ident)); | 
					
						
							|  |  |  |         vorGUI->m_frequencyItem->setData(Qt::DisplayRole, vorGUI->m_navAid->m_frequencykHz / 1000.0); | 
					
						
							|  |  |  |         ui->vorData->setSortingEnabled(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Add to settings to create corresponding demodulator
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         m_settings.m_subChannelSettings.insert(navId, VORLocalizerSubChannelSettings{ | 
					
						
							|  |  |  |             navId, | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             (int)(vorGUI->m_navAid->m_frequencykHz * 1000), | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |             false | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         applySettings(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizer::MsgRemoveVORChannel *msg = VORLocalizer::MsgRemoveVORChannel::create(navId); | 
					
						
							|  |  |  |         m_vorLocalizer->getInputMessageQueue()->push(msg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_selectedVORs.remove(navId); | 
					
						
							|  |  |  |         ui->vorData->removeRow(vorGUI->m_nameItem->row()); | 
					
						
							|  |  |  |         // Remove from settings to remove corresponding demodulator
 | 
					
						
							|  |  |  |         m_settings.m_subChannelSettings.remove(navId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         applySettings(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::updateVORs() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_vorModel.removeAllVORs(); | 
					
						
							|  |  |  |     AzEl azEl = m_azEl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     for (auto vor : m_vors) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         if (vor->m_type.contains("VOR")) // Exclude DMEs
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Calculate distance to VOR from My Position
 | 
					
						
							|  |  |  |             azEl.setTarget(vor->m_latitude, vor->m_longitude, Units::feetToMetres(vor->m_elevation)); | 
					
						
							|  |  |  |             azEl.calculate(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             // Only display VOR if in range
 | 
					
						
							|  |  |  |             if (azEl.getDistance() <= 200000) { | 
					
						
							|  |  |  |                 m_vorModel.addVOR(vor); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | VORLocalizerGUI* VORLocalizerGUI::create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     VORLocalizerGUI* gui = new VORLocalizerGUI(pluginAPI, featureUISet, feature); | 
					
						
							|  |  |  |     return gui; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::destroy() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::resetToDefaults() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.resetToDefaults(); | 
					
						
							|  |  |  |     displaySettings(); | 
					
						
							|  |  |  |     applySettings(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QByteArray VORLocalizerGUI::serialize() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_settings.serialize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool VORLocalizerGUI::deserialize(const QByteArray& data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     if (m_settings.deserialize(data)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-05-13 22:24:48 +02:00
										 |  |  |         m_feature->setWorkspaceIndex(m_settings.m_workspaceIndex); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         displaySettings(); | 
					
						
							|  |  |  |         applySettings(true); | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         resetToDefaults(); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool VORLocalizerGUI::handleMessage(const Message& message) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (VORLocalizer::MsgConfigureVORLocalizer::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("VORLocalizerGUI::handleMessage: VORLocalizer::MsgConfigureVORLocalizer"); | 
					
						
							|  |  |  |         const VORLocalizer::MsgConfigureVORLocalizer& cfg = (VORLocalizer::MsgConfigureVORLocalizer&) message; | 
					
						
							|  |  |  |         m_settings = cfg.getSettings(); | 
					
						
							|  |  |  |         blockApplySettings(true); | 
					
						
							|  |  |  |         displaySettings(); | 
					
						
							|  |  |  |         blockApplySettings(false); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (DSPSignalNotification::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPSignalNotification& notif = (DSPSignalNotification&) message; | 
					
						
							|  |  |  |         m_basebandSampleRate = notif.getSampleRate(); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (VORLocalizerReport::MsgReportRadial::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizerReport::MsgReportRadial& report = (VORLocalizerReport::MsgReportRadial&) message; | 
					
						
							|  |  |  |         int subChannelId = report.getSubChannelId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         VORGUI *vorGUI = m_selectedVORs.value(subChannelId); | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         if (vorGUI) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Display radial and signal magnitudes in table
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             Real varMagDB = std::round(20.0*std::log10(report.getVarMag())); | 
					
						
							|  |  |  |             Real refMagDB = std::round(20.0*std::log10(report.getRefMag())); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             bool validRadial = report.getValidRadial(); | 
					
						
							|  |  |  |             vorGUI->m_radialItem->setData(Qt::DisplayRole, std::round(report.getRadial())); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             if (validRadial) { | 
					
						
							|  |  |  |                 vorGUI->m_radialItem->setForeground(QBrush(Qt::white)); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 vorGUI->m_radialItem->setForeground(QBrush(Qt::red)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             vorGUI->m_refMagItem->setData(Qt::DisplayRole, refMagDB); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             if (report.getValidRefMag()) { | 
					
						
							|  |  |  |                 vorGUI->m_refMagItem->setForeground(QBrush(Qt::white)); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 vorGUI->m_refMagItem->setForeground(QBrush(Qt::red)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             vorGUI->m_varMagItem->setData(Qt::DisplayRole, varMagDB); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             if (report.getValidVarMag()) { | 
					
						
							|  |  |  |                 vorGUI->m_varMagItem->setForeground(QBrush(Qt::white)); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 vorGUI->m_varMagItem->setForeground(QBrush(Qt::red)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             // Update radial on map
 | 
					
						
							|  |  |  |             m_vorModel.setRadial(subChannelId, validRadial, report.getRadial()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug() << "VORLocalizerGUI::handleMessage: Got MsgReportRadial for non-existant subChannelId " << subChannelId; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (VORLocalizerReport::MsgReportIdent::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizerReport::MsgReportIdent& report = (VORLocalizerReport::MsgReportIdent&) message; | 
					
						
							|  |  |  |         int subChannelId = report.getSubChannelId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         VORGUI *vorGUI = m_selectedVORs.value(subChannelId); | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         if (vorGUI) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             QString ident = report.getIdent(); | 
					
						
							|  |  |  |             // Convert Morse to a string
 | 
					
						
							|  |  |  |             QString identString = Morse::toString(ident); | 
					
						
							|  |  |  |             // Idents should only be two or three characters, so filter anything else
 | 
					
						
							|  |  |  |             // other than TEST which indicates a VOR is under maintainance (may also be TST)
 | 
					
						
							|  |  |  |             if (((identString.size() >= 2) && (identString.size() <= 3)) || (identString == "TEST")) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |                 vorGUI->m_rxIdentItem->setText(identString); | 
					
						
							|  |  |  |                 vorGUI->m_rxMorseItem->setText(Morse::toSpacedUnicode(ident)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (vorGUI->m_navAid->m_ident == identString) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // Set colour to green if matching expected ident
 | 
					
						
							|  |  |  |                     vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::green)); | 
					
						
							|  |  |  |                     vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::green)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // Set colour to green if not matching expected ident
 | 
					
						
							|  |  |  |                     vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::red)); | 
					
						
							|  |  |  |                     vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::red)); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |                 // Set yellow to indicate we've filtered something (unless red)
 | 
					
						
							|  |  |  |                 if (vorGUI->m_rxIdentItem->foreground().color() != Qt::red) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::yellow)); | 
					
						
							|  |  |  |                     vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::yellow)); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |             qDebug() << "VORLocalizerGUI::handleMessage: Got MsgReportIdent for non-existant subChannelId " << subChannelId; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (VORLocalizerReport::MsgReportChannels::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizerReport::MsgReportChannels& report = (VORLocalizerReport::MsgReportChannels&) message; | 
					
						
							|  |  |  |         const std::vector<VORLocalizerReport::MsgReportChannels::Channel>& channels = report.getChannels(); | 
					
						
							|  |  |  |         std::vector<VORLocalizerReport::MsgReportChannels::Channel>::const_iterator it = channels.begin(); | 
					
						
							|  |  |  |         ui->channels->clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (; it != channels.end(); ++it) { | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |             ui->channels->addItem(tr("R%1:%2").arg(it->m_deviceSetIndex).arg(it->m_channelIndex)); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     else if (VORLocalizerReport::MsgReportServiceddVORs::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizerReport::MsgReportServiceddVORs& report = (VORLocalizerReport::MsgReportServiceddVORs&) message; | 
					
						
							|  |  |  |         std::vector<int>& servicedVORNavIds = report.getNavIds(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (auto vorGUI : m_selectedVORs) { | 
					
						
							|  |  |  |             vorGUI->m_frequencyItem->setForeground(QBrush(Qt::white)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (auto navId : servicedVORNavIds) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (m_selectedVORs.contains(navId)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 VORGUI *vorGUI = m_selectedVORs[navId]; | 
					
						
							|  |  |  |                 vorGUI->m_frequencyItem->setForeground(QBrush(Qt::green)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-12-08 08:28:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         ui->rrTurnTimeProgress->setMaximum(m_settings.m_rrTime); | 
					
						
							|  |  |  |         ui->rrTurnTimeProgress->setValue(0); | 
					
						
							|  |  |  |         ui->rrTurnTimeProgress->setToolTip(tr("Round robin turn %1s").arg(0)); | 
					
						
							|  |  |  |         m_rrSecondsCount = 0; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::handleInputMessages() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Message* message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while ((message = getInputMessageQueue()->pop()) != 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         if (handleMessage(*message)) { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             delete message; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  | void VORLocalizerGUI::on_startStop_toggled(bool checked) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     if (m_doApplySettings) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         VORLocalizer::MsgStartStop *message = VORLocalizer::MsgStartStop::create(checked); | 
					
						
							|  |  |  |         m_vorLocalizer->getInputMessageQueue()->push(message); | 
					
						
							| 
									
										
										
										
											2022-05-04 08:21:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (checked) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Refresh channels in case device b/w has changed
 | 
					
						
							|  |  |  |             channelsRefresh(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  | void VORLocalizerGUI::on_getOpenAIPVORDB_clicked() | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     // Don't try to download while already in progress
 | 
					
						
							|  |  |  |     if (!m_progressDialog) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         m_progressDialog = new QProgressDialog(this); | 
					
						
							|  |  |  |         m_progressDialog->setMaximum(OpenAIP::m_countryCodes.size()); | 
					
						
							|  |  |  |         m_progressDialog->setCancelButton(nullptr); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         m_openAIP.downloadNavAids(); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  | void VORLocalizerGUI::readNavAids() | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     m_vors = OpenAIP::readNavAids(); | 
					
						
							|  |  |  |     updateVORs(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  | void VORLocalizerGUI::downloadingURL(const QString& url) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-11-03 11:02:04 +00:00
										 |  |  |     if (m_progressDialog) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         m_progressDialog->setLabelText(QString("Downloading %1.").arg(url)); | 
					
						
							|  |  |  |         m_progressDialog->setValue(m_progressDialog->value() + 1); | 
					
						
							| 
									
										
										
										
											2021-11-03 11:02:04 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  | void VORLocalizerGUI::downloadError(const QString& error) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     QMessageBox::critical(this, "VOR Localizer", error); | 
					
						
							|  |  |  |     if (m_progressDialog) | 
					
						
							| 
									
										
										
										
											2021-11-03 11:02:04 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         m_progressDialog->close(); | 
					
						
							| 
									
										
										
										
											2021-11-03 11:02:04 +00:00
										 |  |  |         delete m_progressDialog; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         m_progressDialog = nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  | void VORLocalizerGUI::downloadNavAidsFinished() | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     if (m_progressDialog) { | 
					
						
							|  |  |  |         m_progressDialog->setLabelText("Reading NAVAIDs."); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     readNavAids(); | 
					
						
							|  |  |  |     if (m_progressDialog) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |         m_progressDialog->close(); | 
					
						
							|  |  |  |         delete m_progressDialog; | 
					
						
							|  |  |  |         m_progressDialog = nullptr; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | void VORLocalizerGUI::on_magDecAdjust_toggled(bool checked) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_settings.m_magDecAdjust = checked; | 
					
						
							|  |  |  |     m_vorModel.allVORUpdated(); | 
					
						
							|  |  |  |     applySettings(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | void VORLocalizerGUI::on_rrTime_valueChanged(int value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_rrTime = value; | 
					
						
							|  |  |  |     ui->rrTimeText->setText(tr("%1s").arg(m_settings.m_rrTime)); | 
					
						
							|  |  |  |     applySettings(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::on_centerShift_valueChanged(int value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_centerShift = value * 1000; | 
					
						
							|  |  |  |     ui->centerShiftText->setText(tr("%1k").arg(value)); | 
					
						
							|  |  |  |     applySettings(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 14:53:56 +01:00
										 |  |  | void VORLocalizerGUI::channelsRefresh() | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (m_doApplySettings) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizer::MsgRefreshChannels* message = VORLocalizer::MsgRefreshChannels::create(); | 
					
						
							|  |  |  |         m_vorLocalizer->getInputMessageQueue()->push(message); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::onWidgetRolled(QWidget* widget, bool rollDown) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) widget; | 
					
						
							|  |  |  |     (void) rollDown; | 
					
						
							| 
									
										
										
										
											2021-11-23 13:35:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-24 19:34:48 +02:00
										 |  |  |     RollupContents *rollupContents = getRollupContents(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rollupContents->hasExpandableWidgets()) { | 
					
						
							|  |  |  |         setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Expanding); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Fixed); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int h = rollupContents->height() + getAdditionalHeight(); | 
					
						
							| 
									
										
										
										
											2022-11-08 09:43:58 +00:00
										 |  |  |     int w = std::max(width(), rollupContents->minimumWidth() + gripSize() * 2); | 
					
						
							|  |  |  |     resize(w, h); | 
					
						
							| 
									
										
										
										
											2022-04-24 19:34:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     rollupContents->saveState(m_rollupState); | 
					
						
							| 
									
										
										
										
											2021-11-23 13:35:57 +00:00
										 |  |  |     applySettings(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::onMenuDialogCalled(const QPoint &p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_contextMenuType == ContextMenuChannelSettings) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BasicFeatureSettingsDialog dialog(this); | 
					
						
							|  |  |  |         dialog.setTitle(m_settings.m_title); | 
					
						
							|  |  |  |         dialog.setUseReverseAPI(m_settings.m_useReverseAPI); | 
					
						
							|  |  |  |         dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress); | 
					
						
							|  |  |  |         dialog.setReverseAPIPort(m_settings.m_reverseAPIPort); | 
					
						
							|  |  |  |         dialog.setReverseAPIFeatureSetIndex(m_settings.m_reverseAPIFeatureSetIndex); | 
					
						
							|  |  |  |         dialog.setReverseAPIFeatureIndex(m_settings.m_reverseAPIFeatureIndex); | 
					
						
							| 
									
										
										
										
											2022-04-18 12:08:33 +02:00
										 |  |  |         dialog.setDefaultTitle(m_displayedName); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         dialog.move(p); | 
					
						
							|  |  |  |         dialog.exec(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_settings.m_title = dialog.getTitle(); | 
					
						
							|  |  |  |         m_settings.m_useReverseAPI = dialog.useReverseAPI(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIPort = dialog.getReverseAPIPort(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIFeatureSetIndex = dialog.getReverseAPIFeatureSetIndex(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIFeatureIndex = dialog.getReverseAPIFeatureIndex(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 12:08:33 +02:00
										 |  |  |         setTitle(m_settings.m_title); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         setTitleColor(m_settings.m_rgbColor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         applySettings(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resetContextMenuType(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-30 15:59:51 +01:00
										 |  |  | void VORLocalizerGUI::applyMapSettings() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Get station position
 | 
					
						
							|  |  |  |     Real stationLatitude = MainCore::instance()->getSettings().getLatitude(); | 
					
						
							|  |  |  |     Real stationLongitude = MainCore::instance()->getSettings().getLongitude(); | 
					
						
							|  |  |  |     Real stationAltitude = MainCore::instance()->getSettings().getAltitude(); | 
					
						
							|  |  |  |     m_azEl.setLocation(stationLatitude, stationLongitude, stationAltitude); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QObject *object = item->findChild<QObject*>("map"); | 
					
						
							|  |  |  |     QGeoCoordinate coords; | 
					
						
							|  |  |  |     double zoom; | 
					
						
							|  |  |  |     if (object != nullptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Save existing position of map
 | 
					
						
							|  |  |  |         coords = object->property("center").value<QGeoCoordinate>(); | 
					
						
							|  |  |  |         zoom = object->property("zoomLevel").value<double>(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Center on my location when map is first opened
 | 
					
						
							|  |  |  |         coords.setLatitude(stationLatitude); | 
					
						
							|  |  |  |         coords.setLongitude(stationLongitude); | 
					
						
							|  |  |  |         coords.setAltitude(stationAltitude); | 
					
						
							|  |  |  |         zoom = 10.0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Create the map using the specified provider
 | 
					
						
							|  |  |  |     QQmlProperty::write(item, "mapProvider", m_settings.m_mapProvider); | 
					
						
							|  |  |  |     QVariantMap parameters; | 
					
						
							|  |  |  |     QString mapType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_settings.m_mapProvider == "osm") { | 
					
						
							|  |  |  |         mapType = "Street Map"; | 
					
						
							|  |  |  |     } else if (m_settings.m_mapProvider == "mapboxgl") { | 
					
						
							|  |  |  |         mapType = "mapbox://styles/mapbox/streets-v10"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVariant retVal; | 
					
						
							|  |  |  |     if (!QMetaObject::invokeMethod(item, "createMap", Qt::DirectConnection, | 
					
						
							|  |  |  |                                 Q_RETURN_ARG(QVariant, retVal), | 
					
						
							|  |  |  |                                 Q_ARG(QVariant, QVariant::fromValue(parameters)), | 
					
						
							|  |  |  |                                 Q_ARG(QVariant, mapType), | 
					
						
							|  |  |  |                                 Q_ARG(QVariant, QVariant::fromValue(this)))) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qCritical() << "VORLocalizerGUI::applyMapSettings - Failed to invoke createMap"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     QObject *newMap = retVal.value<QObject *>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Restore position of map
 | 
					
						
							|  |  |  |     if (newMap != nullptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (coords.isValid()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             newMap->setProperty("zoomLevel", QVariant::fromValue(zoom)); | 
					
						
							|  |  |  |             newMap->setProperty("center", QVariant::fromValue(coords)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "VORLocalizerGUI::applyMapSettings - createMap returned a nullptr"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Move antenna icon to My Position
 | 
					
						
							|  |  |  |     QObject *stationObject = newMap->findChild<QObject*>("station"); | 
					
						
							|  |  |  |     if(stationObject != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QGeoCoordinate coords = stationObject->property("coordinate").value<QGeoCoordinate>(); | 
					
						
							|  |  |  |         coords.setLatitude(stationLatitude); | 
					
						
							|  |  |  |         coords.setLongitude(stationLongitude); | 
					
						
							|  |  |  |         coords.setAltitude(stationAltitude); | 
					
						
							|  |  |  |         stationObject->setProperty("coordinate", QVariant::fromValue(coords)); | 
					
						
							|  |  |  |         stationObject->setProperty("stationName", QVariant::fromValue(MainCore::instance()->getSettings().getStationName())); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "VORLocalizerGUI::applyMapSettings - Couldn't find station"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | VORLocalizerGUI::VORLocalizerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : | 
					
						
							|  |  |  |     FeatureGUI(parent), | 
					
						
							|  |  |  |     ui(new Ui::VORLocalizerGUI), | 
					
						
							|  |  |  |     m_pluginAPI(pluginAPI), | 
					
						
							|  |  |  |     m_featureUISet(featureUISet), | 
					
						
							|  |  |  |     m_doApplySettings(true), | 
					
						
							|  |  |  |     m_squelchOpen(false), | 
					
						
							|  |  |  |     m_tickCount(0), | 
					
						
							|  |  |  |     m_progressDialog(nullptr), | 
					
						
							|  |  |  |     m_vorModel(this), | 
					
						
							| 
									
										
										
										
											2020-12-08 08:28:55 +01:00
										 |  |  |     m_lastFeatureState(0), | 
					
						
							|  |  |  |     m_rrSecondsCount(0) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-13 22:24:48 +02:00
										 |  |  |     m_feature = feature; | 
					
						
							| 
									
										
										
										
											2022-04-24 19:34:48 +02:00
										 |  |  |     setAttribute(Qt::WA_DeleteOnClose, true); | 
					
						
							| 
									
										
										
										
											2021-11-24 11:31:51 +00:00
										 |  |  |     m_helpURL = "plugins/feature/vorlocalizer/readme.md"; | 
					
						
							| 
									
										
										
										
											2022-04-24 19:34:48 +02:00
										 |  |  |     RollupContents *rollupContents = getRollupContents(); | 
					
						
							|  |  |  | 	ui->setupUi(rollupContents); | 
					
						
							|  |  |  |     setSizePolicy(rollupContents->sizePolicy()); | 
					
						
							|  |  |  |     rollupContents->arrangeRollups(); | 
					
						
							|  |  |  | 	connect(rollupContents, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ui->map->rootContext()->setContextProperty("vorModel", &m_vorModel); | 
					
						
							|  |  |  |     ui->map->setSource(QUrl(QStringLiteral("qrc:/demodvor/map/map.qml"))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_muteIcon.addPixmap(QPixmap("://sound_off.png"), QIcon::Normal, QIcon::On); | 
					
						
							|  |  |  |     m_muteIcon.addPixmap(QPixmap("://sound_on.png"), QIcon::Normal, QIcon::Off); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     connect(&m_openAIP, &OpenAIP::downloadingURL, this, &VORLocalizerGUI::downloadingURL); | 
					
						
							|  |  |  |     connect(&m_openAIP, &OpenAIP::downloadError, this, &VORLocalizerGUI::downloadError); | 
					
						
							|  |  |  |     connect(&m_openAIP, &OpenAIP::downloadNavAidsFinished, this, &VORLocalizerGUI::downloadNavAidsFinished); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_vorLocalizer = reinterpret_cast<VORLocalizer*>(feature); | 
					
						
							|  |  |  |     m_vorLocalizer->setMessageQueueToGUI(getInputMessageQueue()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     connect(&MainCore::instance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); // 50 ms
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 05:27:12 +01:00
										 |  |  |     m_settings.setRollupState(&m_rollupState); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-30 15:59:51 +01:00
										 |  |  |     applyMapSettings(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Read in VOR information if it exists
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     readNavAids(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Resize the table using dummy data
 | 
					
						
							|  |  |  |     resizeTable(); | 
					
						
							|  |  |  |     // Allow user to reorder columns
 | 
					
						
							|  |  |  |     ui->vorData->horizontalHeader()->setSectionsMovable(true); | 
					
						
							|  |  |  |     // Allow user to sort table by clicking on headers
 | 
					
						
							|  |  |  |     ui->vorData->setSortingEnabled(true); | 
					
						
							|  |  |  |     // Add context menu to allow hiding/showing of columns
 | 
					
						
							|  |  |  |     menu = new QMenu(ui->vorData); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     for (int i = 0; i < ui->vorData->horizontalHeader()->count(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QString text = ui->vorData->horizontalHeaderItem(i)->text(); | 
					
						
							|  |  |  |         menu->addAction(createCheckableItem(text, i, true)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     ui->vorData->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); | 
					
						
							|  |  |  |     connect(ui->vorData->horizontalHeader(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(columnSelectMenu(QPoint))); | 
					
						
							|  |  |  |     // Get signals when columns change
 | 
					
						
							|  |  |  |     connect(ui->vorData->horizontalHeader(), SIGNAL(sectionMoved(int, int, int)), SLOT(vorData_sectionMoved(int, int, int))); | 
					
						
							|  |  |  |     connect(ui->vorData->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), SLOT(vorData_sectionResized(int, int, int))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); | 
					
						
							|  |  |  | 	m_statusTimer.start(1000); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-08 08:28:55 +01:00
										 |  |  |     ui->rrTurnTimeProgress->setMaximum(m_settings.m_rrTime); | 
					
						
							|  |  |  |     ui->rrTurnTimeProgress->setValue(0); | 
					
						
							|  |  |  |     ui->rrTurnTimeProgress->setToolTip(tr("Round robin turn time %1s").arg(0)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:51:39 +01:00
										 |  |  |     // Get updated when position changes
 | 
					
						
							|  |  |  |     connect(&MainCore::instance()->getSettings(), &MainSettings::preferenceChanged, this, &VORLocalizerGUI::preferenceChanged); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     displaySettings(); | 
					
						
							|  |  |  |     applySettings(true); | 
					
						
							| 
									
										
										
										
											2022-05-03 14:53:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     connect(&m_redrawMapTimer, &QTimer::timeout, this, &VORLocalizerGUI::redrawMap); | 
					
						
							|  |  |  |     m_redrawMapTimer.setSingleShot(true); | 
					
						
							|  |  |  |     ui->map->installEventFilter(this); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  |     makeUIConnections(); | 
					
						
							| 
									
										
										
										
											2022-05-03 14:53:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Update channel list when added/removed
 | 
					
						
							|  |  |  |     connect(MainCore::instance(), &MainCore::channelAdded, this, &VORLocalizerGUI::channelsRefresh); | 
					
						
							|  |  |  |     connect(MainCore::instance(), &MainCore::channelRemoved, this, &VORLocalizerGUI::channelsRefresh); | 
					
						
							| 
									
										
										
										
											2022-05-04 08:21:50 +01:00
										 |  |  |     // Also replan when device changed (as bandwidth may change or may becomed fixed center freq)
 | 
					
						
							|  |  |  |     connect(MainCore::instance(), &MainCore::deviceChanged, this, &VORLocalizerGUI::channelsRefresh); | 
					
						
							| 
									
										
										
										
											2022-05-03 14:53:56 +01:00
										 |  |  |     // List already opened channels
 | 
					
						
							|  |  |  |     channelsRefresh(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | VORLocalizerGUI::~VORLocalizerGUI() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-03 14:53:56 +01:00
										 |  |  |     disconnect(&m_redrawMapTimer, &QTimer::timeout, this, &VORLocalizerGUI::redrawMap); | 
					
						
							|  |  |  |     m_redrawMapTimer.stop(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     delete ui; | 
					
						
							| 
									
										
										
										
											2022-05-03 13:44:09 +01:00
										 |  |  |     qDeleteAll(m_vors); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 22:24:48 +02:00
										 |  |  | void VORLocalizerGUI::setWorkspaceIndex(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_workspaceIndex = index; | 
					
						
							|  |  |  |     m_feature->setWorkspaceIndex(index); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | void VORLocalizerGUI::blockApplySettings(bool block) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_doApplySettings = !block; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::applySettings(bool force) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_doApplySettings) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VORLocalizer::MsgConfigureVORLocalizer* message = VORLocalizer::MsgConfigureVORLocalizer::create( m_settings, force); | 
					
						
							|  |  |  |         m_vorLocalizer->getInputMessageQueue()->push(message); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::displaySettings() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setTitleColor(m_settings.m_rgbColor); | 
					
						
							|  |  |  |     setWindowTitle(m_settings.m_title); | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  |     setTitle(m_settings.m_title); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     blockApplySettings(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Order and size columns
 | 
					
						
							|  |  |  |     QHeaderView *header = ui->vorData->horizontalHeader(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < VORLocalizerSettings::VORDEMOD_COLUMNS; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         bool hidden = m_settings.m_columnSizes[i] == 0; | 
					
						
							|  |  |  |         header->setSectionHidden(i, hidden); | 
					
						
							|  |  |  |         menu->actions().at(i)->setChecked(!hidden); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_settings.m_columnSizes[i] > 0) { | 
					
						
							|  |  |  |             ui->vorData->setColumnWidth(i, m_settings.m_columnSizes[i]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         header->moveSection(header->visualIndex(i), m_settings.m_columnIndexes[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     ui->rrTimeText->setText(tr("%1s").arg(m_settings.m_rrTime)); | 
					
						
							|  |  |  |     ui->rrTime->setValue(m_settings.m_rrTime); | 
					
						
							|  |  |  |     ui->centerShiftText->setText(tr("%1k").arg(m_settings.m_centerShift/1000)); | 
					
						
							|  |  |  |     ui->centerShift->setValue(m_settings.m_centerShift/1000); | 
					
						
							| 
									
										
										
										
											2020-12-08 08:28:55 +01:00
										 |  |  |     ui->forceRRAveraging->setChecked(m_settings.m_forceRRAveraging); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  |     getRollupContents()->restoreState(m_rollupState); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     blockApplySettings(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::updateStatus() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int state = m_vorLocalizer->getState(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_lastFeatureState != state) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch (state) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             case Feature::StNotStarted: | 
					
						
							|  |  |  |                 ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case Feature::StIdle: | 
					
						
							|  |  |  |                 ui->startStop->setStyleSheet("QToolButton { background-color : blue; }"); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case Feature::StRunning: | 
					
						
							|  |  |  |                 ui->startStop->setStyleSheet("QToolButton { background-color : green; }"); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case Feature::StError: | 
					
						
							|  |  |  |                 ui->startStop->setStyleSheet("QToolButton { background-color : red; }"); | 
					
						
							|  |  |  |                 QMessageBox::information(this, tr("Message"), m_vorLocalizer->getErrorMessage()); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_lastFeatureState = state; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::tick() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-08 08:28:55 +01:00
										 |  |  |     // Try to determine position, based on intersection of two radials - every second
 | 
					
						
							|  |  |  |     if (++m_tickCount == 20) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         float lat, lon; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_vorModel.findIntersection(lat, lon)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Move antenna icon to estimated position
 | 
					
						
							|  |  |  |             QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |             QObject *stationObject = item->findChild<QObject*>("station"); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             if(stationObject != NULL) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QGeoCoordinate coords = stationObject->property("coordinate").value<QGeoCoordinate>(); | 
					
						
							|  |  |  |                 coords.setLatitude(lat); | 
					
						
							|  |  |  |                 coords.setLongitude(lon); | 
					
						
							|  |  |  |                 stationObject->setProperty("coordinate", QVariant::fromValue(coords)); | 
					
						
							|  |  |  |                 stationObject->setProperty("stationName", QVariant::fromValue(MainCore::instance()->getSettings().getStationName())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-08 08:28:55 +01:00
										 |  |  |         m_rrSecondsCount++; | 
					
						
							|  |  |  |         ui->rrTurnTimeProgress->setMaximum(m_settings.m_rrTime); | 
					
						
							|  |  |  |         ui->rrTurnTimeProgress->setValue(m_rrSecondsCount <= m_settings.m_rrTime ? m_rrSecondsCount : m_settings.m_rrTime); | 
					
						
							|  |  |  |         ui->rrTurnTimeProgress->setToolTip(tr("Round robin turn time %1s").arg(m_rrSecondsCount)); | 
					
						
							|  |  |  |         m_tickCount = 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 13:51:39 +01:00
										 |  |  | void VORLocalizerGUI::preferenceChanged(int elementType) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Preferences::ElementType pref = (Preferences::ElementType)elementType; | 
					
						
							|  |  |  |     if ((pref == Preferences::Latitude) || (pref == Preferences::Longitude) || (pref == Preferences::Altitude)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Real stationLatitude = MainCore::instance()->getSettings().getLatitude(); | 
					
						
							|  |  |  |         Real stationLongitude = MainCore::instance()->getSettings().getLongitude(); | 
					
						
							|  |  |  |         Real stationAltitude = MainCore::instance()->getSettings().getAltitude(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (   (stationLatitude != m_azEl.getLocationSpherical().m_latitude) | 
					
						
							|  |  |  |             || (stationLongitude != m_azEl.getLocationSpherical().m_longitude) | 
					
						
							|  |  |  |             || (stationAltitude != m_azEl.getLocationSpherical().m_altitude)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_azEl.setLocation(stationLatitude, stationLongitude, stationAltitude); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Update distances and what is visible
 | 
					
						
							|  |  |  |             updateVORs(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Update icon position on Map
 | 
					
						
							|  |  |  |             QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |             QObject *map = item->findChild<QObject*>("map"); | 
					
						
							|  |  |  |             if (map != nullptr) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QObject *stationObject = map->findChild<QObject*>("station"); | 
					
						
							|  |  |  |                 if(stationObject != NULL) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     QGeoCoordinate coords = stationObject->property("coordinate").value<QGeoCoordinate>(); | 
					
						
							|  |  |  |                     coords.setLatitude(stationLatitude); | 
					
						
							|  |  |  |                     coords.setLongitude(stationLongitude); | 
					
						
							|  |  |  |                     coords.setAltitude(stationAltitude); | 
					
						
							|  |  |  |                     stationObject->setProperty("coordinate", QVariant::fromValue(coords)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (pref == Preferences::StationName) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Update icon label on Map
 | 
					
						
							|  |  |  |         QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |         QObject *map = item->findChild<QObject*>("map"); | 
					
						
							|  |  |  |         if (map != nullptr) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QObject *stationObject = map->findChild<QObject*>("station"); | 
					
						
							|  |  |  |             if(stationObject != NULL) { | 
					
						
							|  |  |  |                 stationObject->setProperty("stationName", QVariant::fromValue(MainCore::instance()->getSettings().getStationName())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 14:53:56 +01:00
										 |  |  | void VORLocalizerGUI::redrawMap() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // An awful workaround for https://bugreports.qt.io/browse/QTBUG-100333
 | 
					
						
							|  |  |  |     // Also used in ADS-B demod
 | 
					
						
							|  |  |  |     QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |     if (item) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QObject *object = item->findChild<QObject*>("map"); | 
					
						
							|  |  |  |         if (object) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             double zoom = object->property("zoomLevel").value<double>(); | 
					
						
							|  |  |  |             object->setProperty("zoomLevel", QVariant::fromValue(zoom+1)); | 
					
						
							|  |  |  |             object->setProperty("zoomLevel", QVariant::fromValue(zoom)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VORLocalizerGUI::showEvent(QShowEvent *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!event->spontaneous()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Workaround for https://bugreports.qt.io/browse/QTBUG-100333
 | 
					
						
							|  |  |  |         // MapQuickItems can be in wrong position when window is first displayed
 | 
					
						
							|  |  |  |         m_redrawMapTimer.start(500); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool VORLocalizerGUI::eventFilter(QObject *obj, QEvent *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (obj == ui->map) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (event->type() == QEvent::Resize) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Workaround for https://bugreports.qt.io/browse/QTBUG-100333
 | 
					
						
							|  |  |  |             // MapQuickItems can be in wrong position after vertical resize
 | 
					
						
							|  |  |  |             QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event); | 
					
						
							|  |  |  |             QSize oldSize = resizeEvent->oldSize(); | 
					
						
							|  |  |  |             QSize size = resizeEvent->size(); | 
					
						
							|  |  |  |             if (oldSize.height() != size.height()) { | 
					
						
							|  |  |  |                 redrawMap(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  | void VORLocalizerGUI::makeUIConnections() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &VORLocalizerGUI::on_startStop_toggled); | 
					
						
							|  |  |  |     QObject::connect(ui->getOpenAIPVORDB, &QPushButton::clicked, this, &VORLocalizerGUI::on_getOpenAIPVORDB_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->magDecAdjust, &ButtonSwitch::toggled, this, &VORLocalizerGUI::on_magDecAdjust_toggled); | 
					
						
							|  |  |  |     QObject::connect(ui->rrTime, &QDial::valueChanged, this, &VORLocalizerGUI::on_rrTime_valueChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->centerShift, &QDial::valueChanged, this, &VORLocalizerGUI::on_centerShift_valueChanged); | 
					
						
							|  |  |  | } |