From 24d80f8ab0ab14acf7a6d7a02455a9bb071da138 Mon Sep 17 00:00:00 2001 From: srcejon Date: Tue, 17 Sep 2024 09:47:45 +0100 Subject: [PATCH] ADS-B: Allow plugin to be compiled as static lib. Allow building without texttospeech, location or process. VOR localizer: Allow plugin to be compiled as static lib. SID feature: Allow plugin to be compiled as static lib. Satellite Tracker: Allow building without texttospeech or timezone. Map: Allow plugin to be compiled as static lib. Allow building without SSL. APT: Allow plugin to be compiled as static lib. Radio Astronomy: Allow plugin to be compiled as static lib. Allow building without process. ChannelWebAPIUtils: Fix memory leaks. DeviceSampleSource: Add signals that indicate when the position or direction of a device (or it's antenna) has changed. This is to support per device position, which is useful for remote devices not at My Position. --- CMakeLists.txt | 21 +- plugins/channelrx/demodadsb/CMakeLists.txt | 26 +- plugins/channelrx/demodadsb/adsbdemod.cpp | 2 + .../demodadsb/adsbdemoddisplaydialog.cpp | 6 + plugins/channelrx/demodadsb/adsbdemodgui.cpp | 144 +++-- plugins/channelrx/demodadsb/adsbdemodgui.h | 4 + .../{icons.qrc => adsbdemodicons.qrc} | 0 plugins/channelrx/demodadsb/adsbdemodmap.qrc | 31 + plugins/channelrx/demodadsb/flags/china.bmp | Bin 2456 -> 2456 bytes plugins/channelrx/demodadsb/map.qrc | 30 - .../channelrx/demodadsb/map/map_6_strict.qml | 539 ++++++++++++++++++ plugins/channelrx/demodapt/CMakeLists.txt | 16 +- .../demodapt/{icons.qrc => aptdemodicons.qrc} | 0 .../channelrx/radioastronomy/CMakeLists.txt | 16 +- .../radioastronomy/radioastronomy.cpp | 8 + .../{icons.qrc => radioastronomyicons.qrc} | 0 plugins/feature/map/CMakeLists.txt | 22 +- plugins/feature/map/map.qrc | 1 + plugins/feature/map/map/antennaangel.png | Bin 0 -> 3857 bytes plugins/feature/map/{data.qrc => mapdata.qrc} | 0 plugins/feature/map/mapguinowebengine.ui | 97 +++- .../feature/map/{icons.qrc => mapicons.qrc} | 0 plugins/feature/map/mapitem.cpp | 2 - plugins/feature/map/maptileserver.h | 4 + .../satellitetracker/satellitetrackergui.cpp | 17 +- .../satellitetracker/satellitetrackergui.h | 2 + .../satellitetracker/satellitetrackersgp4.cpp | 4 + .../satellitetrackerworker.cpp | 4 + plugins/feature/sid/CMakeLists.txt | 16 +- plugins/feature/sid/readme.md | 6 +- plugins/feature/sid/sidgui.cpp | 10 +- .../feature/sid/{icons.qrc => sidicons.qrc} | 0 plugins/feature/vorlocalizer/CMakeLists.txt | 18 +- .../{icons.qrc => vorlocalizericons.qrc} | 0 .../{map.qrc => vorlocalizermap.qrc} | 0 sdrbase/channel/channelwebapiutils.cpp | 109 ++-- sdrbase/channel/channelwebapiutils.h | 3 +- sdrbase/dsp/devicesamplesource.h | 4 + 38 files changed, 1010 insertions(+), 152 deletions(-) rename plugins/channelrx/demodadsb/{icons.qrc => adsbdemodicons.qrc} (100%) create mode 100644 plugins/channelrx/demodadsb/adsbdemodmap.qrc delete mode 100644 plugins/channelrx/demodadsb/map.qrc create mode 100644 plugins/channelrx/demodadsb/map/map_6_strict.qml rename plugins/channelrx/demodapt/{icons.qrc => aptdemodicons.qrc} (100%) rename plugins/channelrx/radioastronomy/{icons.qrc => radioastronomyicons.qrc} (100%) create mode 100644 plugins/feature/map/map/antennaangel.png rename plugins/feature/map/{data.qrc => mapdata.qrc} (100%) rename plugins/feature/map/{icons.qrc => mapicons.qrc} (100%) rename plugins/feature/sid/{icons.qrc => sidicons.qrc} (100%) rename plugins/feature/vorlocalizer/{icons.qrc => vorlocalizericons.qrc} (100%) rename plugins/feature/vorlocalizer/{map.qrc => vorlocalizermap.qrc} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36403c39dd..4ec925d53d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -728,8 +728,27 @@ if (BUILD_GUI) endif() endif() +# List of static plugins to link with - This is appended to by each pluging CMakeLists.txt +set_property(GLOBAL PROPERTY STATIC_PLUGINS_PROPERTY "") + +if(Qt${QT_DEFAULT_MAJOR_VERSION}Positioning_FOUND) + add_compile_definitions(QT_POSITIONING_FOUND) +endif() +if(Qt${QT_DEFAULT_MAJOR_VERSION}Location_FOUND) + add_compile_definitions(QT_LOCATION_FOUND) +endif() +if(Qt${QT_DEFAULT_MAJOR_VERSION}Charts_FOUND) + add_compile_definitions(QT_CHARTS_FOUND) +endif() +if(Qt${QT_DEFAULT_MAJOR_VERSION}TextToSpeech_FOUND) + add_compile_definitions(QT_TEXTTOSPEECH_FOUND) +endif() +if(BUILD_SHARED_LIBS) + add_compile_definitions(BUILD_SHARED_LIBS) +endif() + # other requirements -if(NOT ANDROID) +if(NOT ANDROID AND NOT EMSCRIPTEN) find_package(PkgConfig REQUIRED) endif() diff --git a/plugins/channelrx/demodadsb/CMakeLists.txt b/plugins/channelrx/demodadsb/CMakeLists.txt index 4c999515ff..851ad7bfab 100644 --- a/plugins/channelrx/demodadsb/CMakeLists.txt +++ b/plugins/channelrx/demodadsb/CMakeLists.txt @@ -43,10 +43,10 @@ if(NOT SERVER_MODE) adsbdemodnotificationdialog.cpp adsbdemodnotificationdialog.ui adsbosmtemplateserver.cpp + adsbdemodmap.qrc + adsbdemodicons.qrc airlinelogos.qrc flags.qrc - map.qrc - icons.qrc ) set(adsb_HEADERS ${adsb_HEADERS} @@ -60,7 +60,13 @@ if(NOT SERVER_MODE) ) set(TARGET_NAME ${PLUGINS_PREFIX}demodadsb) - set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning Qt::Location Qt::TextToSpeech) + set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning) + if(Qt${QT_DEFAULT_MAJOR_VERSION}Location_FOUND) + list(APPEND TARGET_LIB Qt::Location) + endif() + if(Qt${QT_DEFAULT_MAJOR_VERSION}TextToSpeech_FOUND) + list(APPEND TARGET_LIB Qt::TextToSpeech) + endif() set(TARGET_LIB_GUI "sdrgui") set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR}) else() @@ -70,15 +76,21 @@ else() set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) endif() -add_library(${TARGET_NAME} SHARED - ${adsb_SOURCES} -) +if(NOT Qt6_FOUND) + add_library(${TARGET_NAME} ${adsb_SOURCES}) +else() + qt_add_plugin(${TARGET_NAME} CLASS_NAME ADSBPlugin ${adsb_SOURCES}) +endif() + +if(NOT BUILD_SHARED_LIBS) + set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME}) +endif() if (NOT WIN32) link_directories(${Boost_LIBRARY_DIRS}) endif() -target_link_libraries(${TARGET_NAME} +target_link_libraries(${TARGET_NAME} PRIVATE Boost::disable_autolinking Qt::Core ${TARGET_LIB} diff --git a/plugins/channelrx/demodadsb/adsbdemod.cpp b/plugins/channelrx/demodadsb/adsbdemod.cpp index 30eec3eba1..ef23daeff4 100644 --- a/plugins/channelrx/demodadsb/adsbdemod.cpp +++ b/plugins/channelrx/demodadsb/adsbdemod.cpp @@ -157,7 +157,9 @@ void ADSBDemod::stop() m_basebandSink->stopWork(); m_worker->stopWork(); m_thread->exit(); +#ifndef __EMSCRIPTEN__ m_thread->wait(); +#endif } bool ADSBDemod::handleMessage(const Message& cmd) diff --git a/plugins/channelrx/demodadsb/adsbdemoddisplaydialog.cpp b/plugins/channelrx/demodadsb/adsbdemoddisplaydialog.cpp index 64017ae342..06653e7b4f 100644 --- a/plugins/channelrx/demodadsb/adsbdemoddisplaydialog.cpp +++ b/plugins/channelrx/demodadsb/adsbdemoddisplaydialog.cpp @@ -16,7 +16,9 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#ifdef QT_LOCATION_FOUND #include +#endif #include #include "adsbdemoddisplaydialog.h" @@ -30,6 +32,7 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid { ui->setupUi(this); +#ifdef QT_LOCATION_FOUND QStringList mapProviders = QGeoServiceProvider::availableServiceProviders(); if (!mapProviders.contains("osm")) { ui->mapProvider->removeItem(ui->mapProvider->findText("osm")); @@ -37,6 +40,9 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid if (!mapProviders.contains("mapboxgl")) { ui->mapProvider->removeItem(ui->mapProvider->findText("mapboxgl")); } +#else + QStringList mapProviders; +#endif ui->timeout->setValue(settings->m_removeTimeout); ui->aircraftMinZoom->setValue(settings->m_aircraftMinZoom); diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.cpp b/plugins/channelrx/demodadsb/adsbdemodgui.cpp index dc958a67f4..2db5239218 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.cpp +++ b/plugins/channelrx/demodadsb/adsbdemodgui.cpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020 Edouard Griffiths, F4EXB // -// Copyright (C) 2020 Jon Beniston, M7RCE // +// Copyright (C) 2020-2024 Jon Beniston, M7RCE // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -34,10 +34,13 @@ #include #include #include +#ifdef QT_LOCATION_FOUND #include +#endif #include "ui_adsbdemodgui.h" #include "device/deviceapi.h" +#include "dsp/devicesamplesource.h" #include "channel/channelwebapiutils.h" #include "feature/featurewebapiutils.h" #include "plugin/pluginapi.h" @@ -3323,6 +3326,7 @@ void ADSBDemodGUI::checkDynamicNotification(Aircraft *aircraft) // has speech notifications configured void ADSBDemodGUI::enableSpeechIfNeeded() { +#ifdef QT_TEXTTOSPEECH_FOUND if (m_speech) { return; } @@ -3335,19 +3339,25 @@ void ADSBDemodGUI::enableSpeechIfNeeded() return; } } +#endif } void ADSBDemodGUI::speechNotification(Aircraft *aircraft, const QString &speech) { +#ifdef QT_TEXTTOSPEECH_FOUND if (m_speech) { m_speech->say(subAircraftString(aircraft, speech)); } else { - qDebug() << "ADSBDemodGUI::speechNotification: Unable to say " << speech; + qWarning() << "ADSBDemodGUI::speechNotification: Unable to say " << speech; } +#else + qWarning() << "ADSBDemodGUI::speechNotification: TextToSpeech not supported. Unable to say " << speech; +#endif } void ADSBDemodGUI::commandNotification(Aircraft *aircraft, const QString &command) { +#if QT_CONFIG(process) QString commandLine = subAircraftString(aircraft, command); QStringList allArgs = QProcess::splitCommand(commandLine); @@ -3357,6 +3367,9 @@ void ADSBDemodGUI::commandNotification(Aircraft *aircraft, const QString &comman allArgs.pop_front(); QProcess::startDetached(program, allArgs); } +#else + qWarning() << "ADSBDemodGUI::commandNotification: QProcess not supported. Can't run: " << command; +#endif } QString ADSBDemodGUI::subAircraftString(Aircraft *aircraft, const QString &string) @@ -3606,6 +3619,7 @@ void ADSBDemodGUI::on_findOnMapFeature_clicked() // Find aircraft on channel map void ADSBDemodGUI::findOnChannelMap(Aircraft *aircraft) { +#ifdef QT_LOCATION_FOUND if (aircraft->m_positionValid) { QQuickItem *item = ui->map->rootObject(); @@ -3618,6 +3632,7 @@ void ADSBDemodGUI::findOnChannelMap(Aircraft *aircraft) object->setProperty("center", QVariant::fromValue(geocoord)); } } +#endif } void ADSBDemodGUI::adsbData_customContextMenuRequested(QPoint pos) @@ -4682,6 +4697,7 @@ void ADSBDemodGUI::on_displaySettings_clicked() { bool oldSiUnits = m_settings.m_siUnits; ADSBDemodDisplayDialog dialog(&m_settings); + new DialogPositioner(&dialog, true); if (dialog.exec() == QDialog::Accepted) { bool unitsChanged = m_settings.m_siUnits != oldSiUnits; @@ -4695,6 +4711,7 @@ void ADSBDemodGUI::on_displaySettings_clicked() void ADSBDemodGUI::applyMapSettings() { +#ifdef QT_LOCATION_FOUND Real stationLatitude = MainCore::instance()->getSettings().getLatitude(); Real stationLongitude = MainCore::instance()->getSettings().getLongitude(); Real stationAltitude = MainCore::instance()->getSettings().getAltitude(); @@ -4743,8 +4760,13 @@ void ADSBDemodGUI::applyMapSettings() if (mapProvider == "osm") { +#ifdef __EMSCRIPTEN__ + // Default is http://maps-redirect.qt.io/osm/5.8/ and Emscripten needs https + parameters["osm.mapping.providersrepository.address"] = QString("https://sdrangel.beniston.com/sdrangel/maps/"); +#else // Use our repo, so we can append API key and redefine transmit maps parameters["osm.mapping.providersrepository.address"] = QString("http://127.0.0.1:%1/").arg(m_osmPort); +#endif // Use ADS-B specific cache, as we use different transmit maps QString cachePath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/QtLocation/5.8/tiles/osm/sdrangel_adsb"; parameters["osm.mapping.cache.directory"] = cachePath; @@ -4831,6 +4853,7 @@ void ADSBDemodGUI::applyMapSettings() { qDebug() << "ADSBDemodGUI::applyMapSettings - createMap returned a nullptr"; } +#endif // QT_LOCATION_FOUND } // Called from QML when empty space clicked @@ -4875,12 +4898,15 @@ ADSBDemodGUI::ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb { QSurfaceFormat format; format.setSamples(multisamples); +#ifdef QT_LOCATION_FOUND ui->map->setFormat(format); +#endif } m_osmPort = 0; // Pick a free port m_templateServer = new ADSBOSMTemplateServer("q2RVNAe3eFKCH4XsrE3r", m_osmPort); +#ifdef QT_LOCATION_FOUND ui->map->setAttribute(Qt::WA_AcceptTouchEvents, true); ui->map->rootContext()->setContextProperty("aircraftModel", &m_aircraftModel); @@ -4889,9 +4915,17 @@ ADSBDemodGUI::ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb ui->map->rootContext()->setContextProperty("navAidModel", &m_navAidModel); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) ui->map->setSource(QUrl(QStringLiteral("qrc:/map/map.qml"))); +#elif defined(__EMSCRIPTEN__) + // No Qt5Compat.GraphicalEffects + ui->map->setSource(QUrl(QStringLiteral("qrc:/map/map_6_strict.qml"))); #else - ui->map->setSource(QUrl(QStringLiteral("qrc:/map/map_6.qml"))); + ui->map->setSource(QUrl(QStringLiteral("qrc:/map/map_6_strict.qml"))); #endif + ui->map->installEventFilter(this); +#else + ui->map->hide(); +#endif + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); m_adsbDemod = reinterpret_cast(rxChannel); //new ADSBDemod(m_deviceUISet->m_deviceSourceAPI); @@ -4991,12 +5025,15 @@ ADSBDemodGUI::ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb m_azEl.setLocation(stationLatitude, stationLongitude, stationAltitude); // These are the default values in sdrbase/settings/preferences.cpp - if ((stationLatitude == (float)49.012423) && (stationLongitude == (float)8.418125)) { + if ((stationLatitude == 49.012423f) && (stationLongitude == 8.418125f)) { ui->warning->setText("Please set your antenna location under Preferences > My Position"); } // Get updated when position changes connect(&MainCore::instance()->getSettings(), &MainSettings::preferenceChanged, this, &ADSBDemodGUI::preferenceChanged); + if (m_deviceUISet->m_deviceAPI->getSampleSource()) { + connect(m_deviceUISet->m_deviceAPI->getSampleSource(), &DeviceSampleSource::positionChanged, this, &ADSBDemodGUI::devicePositionChanged); + } // Get airport weather when requested connect(&m_airportModel, &AirportModel::requestMetar, this, &ADSBDemodGUI::requestMetar); @@ -5034,7 +5071,6 @@ ADSBDemodGUI::ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb connect(&m_redrawMapTimer, &QTimer::timeout, this, &ADSBDemodGUI::redrawMap); m_redrawMapTimer.setSingleShot(true); - ui->map->installEventFilter(this); DialPopup::addPopupsToChildDials(this); m_resizer.enableChildMouseTracking(); } @@ -5194,12 +5230,19 @@ void ADSBDemodGUI::displaySettings() initFlightInformation(); initAviationWeather(); - applyMapSettings(); applyImportSettings(); getRollupContents()->restoreState(m_rollupState); blockApplySettings(false); enableSpeechIfNeeded(); +#ifdef __EMSCRIPTEN__ + // FIXME: If we don't have this delay, tile server requests get deleted + QTimer::singleShot(250, [this] { + applyMapSettings(); + }); +#else + applyMapSettings(); +#endif } void ADSBDemodGUI::leaveEvent(QEvent* event) @@ -5752,6 +5795,7 @@ int ADSBDemodGUI::grayToBinary(int gray, int bits) const void ADSBDemodGUI::redrawMap() { +#ifdef QT_LOCATION_FOUND // An awful workaround for https://bugreports.qt.io/browse/QTBUG-100333 // Also used in Map feature QQuickItem *item = ui->map->rootObject(); @@ -5765,6 +5809,7 @@ void ADSBDemodGUI::redrawMap() object->setProperty("zoomLevel", QVariant::fromValue(zoom)); } } +#endif } void ADSBDemodGUI::showEvent(QShowEvent *event) @@ -5976,54 +6021,70 @@ void ADSBDemodGUI::handleImportReply(QNetworkReply* reply) } } -void ADSBDemodGUI::preferenceChanged(int elementType) +void ADSBDemodGUI::updatePosition(float latitude, float longitude, float altitude) { - 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(); + // Use device postion in preference to My Position + ChannelWebAPIUtils::getDevicePosition(getDeviceSetIndex(), latitude, longitude, altitude); - QGeoCoordinate stationPosition(stationLatitude, stationLongitude, stationAltitude); - QGeoCoordinate previousPosition(m_azEl.getLocationSpherical().m_latitude, m_azEl.getLocationSpherical().m_longitude, m_azEl.getLocationSpherical().m_altitude); + QGeoCoordinate stationPosition(latitude, longitude, altitude); + QGeoCoordinate previousPosition(m_azEl.getLocationSpherical().m_latitude, m_azEl.getLocationSpherical().m_longitude, m_azEl.getLocationSpherical().m_altitude); - if (stationPosition != previousPosition) - { - m_azEl.setLocation(stationLatitude, stationLongitude, stationAltitude); + if (stationPosition != previousPosition) + { + m_azEl.setLocation(latitude, longitude, altitude); - // Update distances and what is visible, but only do it if position has changed significantly - if (!m_lastFullUpdatePosition.isValid() || (stationPosition.distanceTo(m_lastFullUpdatePosition) >= 1000)) - { - updateAirports(); - updateAirspaces(); - updateNavAids(); - m_lastFullUpdatePosition = stationPosition; - } + // Update distances and what is visible, but only do it if position has changed significantly + if (!m_lastFullUpdatePosition.isValid() || (stationPosition.distanceTo(m_lastFullUpdatePosition) >= 1000)) + { + updateAirports(); + updateAirspaces(); + updateNavAids(); + m_lastFullUpdatePosition = stationPosition; + } - // Update icon position on Map - QQuickItem *item = ui->map->rootObject(); +#ifdef QT_LOCATION_FOUND + // Update icon position on Map + QQuickItem *item = ui->map->rootObject(); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) - QObject *map = item->findChild("map"); + QObject *map = item->findChild("map"); #else - QObject *map = item->findChild("mapView"); + QObject *map = item->findChild("mapView"); #endif - if (map != nullptr) + if (map != nullptr) + { + QObject *stationObject = map->findChild("station"); + if(stationObject != NULL) { - QObject *stationObject = map->findChild("station"); - if(stationObject != NULL) - { - QGeoCoordinate coords = stationObject->property("coordinate").value(); - coords.setLatitude(stationLatitude); - coords.setLongitude(stationLongitude); - coords.setAltitude(stationAltitude); - stationObject->setProperty("coordinate", QVariant::fromValue(coords)); - } + QGeoCoordinate coords = stationObject->property("coordinate").value(); + coords.setLatitude(latitude); + coords.setLongitude(longitude); + coords.setAltitude(altitude); + stationObject->setProperty("coordinate", QVariant::fromValue(coords)); } } +#endif + } +} + +void ADSBDemodGUI::devicePositionChanged(float latitude, float longitude, float altitude) +{ + updatePosition(latitude, longitude, altitude); +} + +void ADSBDemodGUI::preferenceChanged(int elementType) +{ + Preferences::ElementType pref = (Preferences::ElementType)elementType; + if ((pref == Preferences::Latitude) || (pref == Preferences::Longitude) || (pref == Preferences::Altitude)) + { + Real myLatitude = MainCore::instance()->getSettings().getLatitude(); + Real myLongitude = MainCore::instance()->getSettings().getLongitude(); + Real myAltitude = MainCore::instance()->getSettings().getAltitude(); + + updatePosition(myLatitude, myLongitude, myAltitude); } else if (pref == Preferences::StationName) { +#ifdef QT_LOCATION_FOUND // Update icon label on Map QQuickItem *item = ui->map->rootObject(); #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) @@ -6038,11 +6099,14 @@ void ADSBDemodGUI::preferenceChanged(int elementType) stationObject->setProperty("stationName", QVariant::fromValue(MainCore::instance()->getSettings().getStationName())); } } +#endif } else if (pref == Preferences::MapSmoothing) { +#ifdef QT_LOCATION_FOUND QQuickItem *item = ui->map->rootObject(); QQmlProperty::write(item, "smoothing", MainCore::instance()->getSettings().getMapSmoothing()); +#endif } } diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.h b/plugins/channelrx/demodadsb/adsbdemodgui.h index d083798575..89793713e3 100644 --- a/plugins/channelrx/demodadsb/adsbdemodgui.h +++ b/plugins/channelrx/demodadsb/adsbdemodgui.h @@ -941,7 +941,9 @@ public slots: ADSBDemodSettings::AirportType m_currentAirportMinimumSize; bool m_currentDisplayHeliports; +#ifdef QT_TEXTTOSPEECH_FOUND QTextToSpeech *m_speech; +#endif QMenu *menu; // Column select context menu FlightInformation *m_flightInformation; PlaneSpotters m_planeSpotters; @@ -1039,6 +1041,7 @@ public slots: void redrawMap(); void applyImportSettings(); void sendAircraftReport(); + void updatePosition(float latitude, float longitude, float altitude); void leaveEvent(QEvent*); void enterEvent(EnterEventType*); @@ -1092,6 +1095,7 @@ private slots: void import(); void handleImportReply(QNetworkReply* reply); void preferenceChanged(int elementType); + void devicePositionChanged(float latitude, float longitude, float altitude); void requestMetar(const QString& icao); void weatherUpdated(const AviationWeather::METAR &metar); diff --git a/plugins/channelrx/demodadsb/icons.qrc b/plugins/channelrx/demodadsb/adsbdemodicons.qrc similarity index 100% rename from plugins/channelrx/demodadsb/icons.qrc rename to plugins/channelrx/demodadsb/adsbdemodicons.qrc diff --git a/plugins/channelrx/demodadsb/adsbdemodmap.qrc b/plugins/channelrx/demodadsb/adsbdemodmap.qrc new file mode 100644 index 0000000000..574ca4c50a --- /dev/null +++ b/plugins/channelrx/demodadsb/adsbdemodmap.qrc @@ -0,0 +1,31 @@ + + + map/map.qml + map/map_6.qml + map/map_6_strict.qml + map/ModifiedMapView.qml + map/MapStation.qml + map/aircraft_2engine.png + map/aircraft_2enginesmall.png + map/aircraft_4engine.png + map/aircraft_helicopter.png + map/aircraft_light.png + map/aircraft_space.png + map/aircraft_drone.png + map/aircraft_fighter.png + map/airport_large.png + map/airport_medium.png + map/airport_small.png + map/heliport.png + map/antenna.png + map/truck.png + map/VOR.png + map/VOR-DME.png + map/VORTAC.png + map/DVOR.png + map/DVOR-DME.png + map/DVORTAC.png + map/NDB.png + map/DME.png + + diff --git a/plugins/channelrx/demodadsb/flags/china.bmp b/plugins/channelrx/demodadsb/flags/china.bmp index c47980874cd61d21f0234b840d5c900bf1ca66b7..0a4edbb11133a4507320dbf0f1a3f510b389f67b 100644 GIT binary patch literal 2456 zcmeHJO-sWt7;bM94_)Wl^;@R46+9~bfPqIZf_M;Rh*QCX;LSfGJ9+ch2>uci=Nhrt zLw(Yg?y_O2DR@|UlfFsQJb9k?O~~MIydq`KKI-kFbn%uYBkRAw_s(iwvJO-m-rJT- z1e)*ADh9+V!-S7n;tH2^?u1L7=gK0y^WW+0(mpX%}W7=PT zDRBdX`ZhQ2I5g0Rc@=5IgspD9E{L&vj(aeQ{$kvcK$C2r86fz)*?`U<vB0eW literal 2456 zcmZ?rox#Zf24+A~1Byj}G$VrqSUd?RFT@SOU;!W@q;YQ)jfTKz2#kgRnIWKgPe}Ei zkn&xic46ha!U}hV74HhE-4jv=i_@-nQN1r{`B2d1k&xnDL8nK2QP25;o(dS=7gW6` zXz@@;?LL{_A>?2|`MZ3vPuVa3a0 zneYE)-S?fZ_6_Tkf4uR}h2&{vub|>xzPM-XH-B+#|H^#-ALo=0!s_>hbRRN5{Kr%H zN=WVw)dLx7pxRx2-FrN(Z - - map/map.qml - map/map_6.qml - map/ModifiedMapView.qml - map/MapStation.qml - map/aircraft_2engine.png - map/aircraft_2enginesmall.png - map/aircraft_4engine.png - map/aircraft_helicopter.png - map/aircraft_light.png - map/aircraft_space.png - map/aircraft_drone.png - map/aircraft_fighter.png - map/airport_large.png - map/airport_medium.png - map/airport_small.png - map/heliport.png - map/antenna.png - map/truck.png - map/VOR.png - map/VOR-DME.png - map/VORTAC.png - map/DVOR.png - map/DVOR-DME.png - map/DVORTAC.png - map/NDB.png - map/DME.png - - diff --git a/plugins/channelrx/demodadsb/map/map_6_strict.qml b/plugins/channelrx/demodadsb/map/map_6_strict.qml new file mode 100644 index 0000000000..ea3155203e --- /dev/null +++ b/plugins/channelrx/demodadsb/map/map_6_strict.qml @@ -0,0 +1,539 @@ +import QtQuick 2.14 +import QtQuick.Window 2.14 +import QtQuick.Controls 2.14 +import QtPositioning 6.5 +import QtLocation 6.5 +import QtQuick.Effects + +Item { + id: qmlMap + property int aircraftZoomLevel: 11 + property int aircraftMinZoomLevel: 11 + property int airportZoomLevel: 11 + property string mapProvider: "osm" + property variant mapPtr + property string requestedMapType + property bool lightIcons + property variant guiPtr + property bool smoothing + + function createMap(pluginParameters, requestedMap, gui) { + requestedMapType = requestedMap + guiPtr = gui + + var paramString = "" + for (var prop in pluginParameters) { + var parameter = 'PluginParameter { name: "' + prop + '"; value: "' + pluginParameters[prop] + '"}' + paramString = paramString + parameter + } + var pluginString = 'import QtLocation 6.5; Plugin{ name:"' + mapProvider + '"; ' + paramString + '}' + var plugin = Qt.createQmlObject (pluginString, qmlMap) + + if (mapPtr) { + // Objects aren't destroyed immediately, so don't call findChild("map") + mapPtr.destroy() + mapPtr = null + } + mapPtr = actualMapComponent.createObject(page) + mapPtr.map.plugin = plugin + mapPtr.map.forceActiveFocus() + return mapPtr + } + + Item { + id: page + anchors.fill: parent + } + + Component { + id: actualMapComponent + + ModifiedMapView { + id: mapView + objectName: "mapView" + anchors.fill: parent + map.center: QtPositioning.coordinate(51.5, 0.125) // London + map.zoomLevel: 10 + map.objectName: "map" + + // not in 6 + //gesture.enabled: true + //gesture.acceptedGestures: MapGestureArea.PinchGesture | MapGestureArea.PanGesture + + MouseArea { + anchors.fill: parent + propagateComposedEvents: true + onClicked: { + // Unhighlight current aircraft + guiPtr.clearHighlighted() + mouse.accepted = false + } + } + + MapStation { + id: station + objectName: "station" + stationName: "Home" + parent: mapView.map + } + + MapItemView { + model: airspaceModel + delegate: airspaceComponent + parent: mapView.map + } + + MapItemView { + model: navAidModel + delegate: navAidComponent + parent: mapView.map + } + + MapItemView { + model: airspaceModel + delegate: airspaceNameComponent + parent: mapView.map + } + + MapItemView { + model: airportModel + delegate: airportComponent + parent: mapView.map + } + + // This needs to be before aircraftComponent MapItemView, so it's drawn underneath + MapItemView { + model: aircraftModel + delegate: aircraftPathComponent + parent: mapView.map + } + + MapItemView { + model: aircraftModel + delegate: aircraftComponent + parent: mapView.map + } + + map.onZoomLevelChanged: { + if (map.zoomLevel > aircraftMinZoomLevel) { + aircraftZoomLevel = map.zoomLevel + } else { + aircraftZoomLevel = aircraftMinZoomLevel + } + if (map.zoomLevel > 11) { + station.zoomLevel = map.zoomLevel + airportZoomLevel = map.zoomLevel + } else { + station.zoomLevel = 11 + airportZoomLevel = 11 + } + } + + map.onSupportedMapTypesChanged : { + for (var i = 0; i < map.supportedMapTypes.length; i++) { + if (requestedMapType == map.supportedMapTypes[i].name) { + map.activeMapType = map.supportedMapTypes[i] + } + } + lightIcons = (requestedMapType == "Night Transit Map") || (requestedMapType == "mapbox://styles/mapbox/dark-v9") + } + + } + } + + Component { + id: navAidComponent + MapQuickItem { + id: navAid + anchorPoint.x: image.width/2 + anchorPoint.y: image.height/2 + coordinate: position + zoomLevel: airportZoomLevel + + sourceItem: Grid { + columns: 1 + Grid { + horizontalItemAlignment: Grid.AlignHCenter + columnSpacing: 5 + layer.enabled: smoothing + layer.smooth: smoothing + Image { + id: image + source: navAidImage + visible: !lightIcons + MouseArea { + anchors.fill: parent + onClicked: (mouse) => { + selected = !selected + } + } + } + MultiEffect { + width: image.width + height: image.height + source: image + brightness: 1.0 + colorization: 1.0 + colorizationColor: "#c0ffffff" + visible: lightIcons + } + Rectangle { + id: bubble + color: bubbleColour + border.width: 1 + width: text.width + 5 + height: text.height + 5 + radius: 5 + Text { + id: text + anchors.centerIn: parent + text: navAidData + } + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: (mouse) => { + selected = !selected + } + } + } + } + } + } + } + + Component { + id: airspaceComponent + MapPolygon { + border.width: 1 + border.color: airspaceBorderColor + color: airspaceFillColor + path: airspacePolygon + } + } + + Component { + id: airspaceNameComponent + MapQuickItem { + coordinate: position + anchorPoint.x: airspaceText.width/2 + anchorPoint.y: airspaceText.height/2 + zoomLevel: airportZoomLevel + sourceItem: Grid { + columns: 1 + Grid { + layer.enabled: smoothing + layer.smooth: smoothing + horizontalItemAlignment: Grid.AlignHCenter + Text { + id: airspaceText + text: details + } + } + } + } + } + + Component { + id: aircraftPathComponent + MapPolyline { + line.width: 2 + line.color: 'gray' + path: aircraftPath + } + } + + Component { + id: aircraftComponent + MapQuickItem { + id: aircraft + anchorPoint.x: image.width/2 + anchorPoint.y: image.height/2 + coordinate: position + zoomLevel: aircraftZoomLevel + + sourceItem: Grid { + columns: 1 + Grid { + layer.enabled: smoothing + layer.smooth: smoothing + horizontalItemAlignment: Grid.AlignHCenter + Image { + id: image + rotation: heading + source: aircraftImage + visible: !lightIcons + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if (mouse.button === Qt.LeftButton) { + highlighted = true + console.log("z=" + aircraft.sourceItem.z) + aircraft.sourceItem.z = aircraft.sourceItem.z + 1 + } else if (mouse.button === Qt.RightButton) { + contextMenu.popup() + } + } + onDoubleClicked: { + target = true + } + } + } + MultiEffect { + width: image.width + height: image.height + rotation: heading + source: image + brightness: 1.0 + colorization: 1.0 + colorizationColor: "#c0ffffff" + visible: lightIcons + MouseArea { + anchors.fill: parent + onClicked: { + highlighted = true + } + onDoubleClicked: { + target = true + } + } + } + Rectangle { + id: bubble + color: bubbleColour + border.width: 1 + width: text.width * 1.1 + height: text.height * 1.1 + radius: 5 + Text { + id: text + anchors.centerIn: parent + text: adsbData + textFormat: TextEdit.RichText + } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if (mouse.button === Qt.LeftButton) { + showAll = !showAll + } else if (mouse.button === Qt.RightButton) { + contextMenu.popup() + } + } + Menu { + id: contextMenu + MenuItem { + text: "Set as target" + onTriggered: target = true + } + MenuItem { + text: "Find on feature map" + onTriggered: aircraftModel.findOnMap(index) + } + } + } + } + } + } + } + } + + Component { + id: airportComponent + MapItemGroup { + MapItemGroup { + property var groupVisible: false + id: rangeGroup + MapCircle { + id: circle5nm + center: position + color: "transparent" + border.color: "gray" + radius: 9260 // 5nm in metres + visible: rangeGroup.groupVisible + } + MapCircle { + id: circle10nm + center: position + color: "transparent" + border.color: "gray" + radius: 18520 + visible: rangeGroup.groupVisible + } + MapCircle { + id: circle15nm + center: airport.coordinate + color: "transparent" + border.color: "gray" + radius: 27780 + visible: rangeGroup.groupVisible + } + MapQuickItem { + id: text5nm + coordinate { + latitude: position.latitude + longitude: position.longitude + (5/60)/Math.cos(Math.abs(position.latitude)*Math.PI/180) + } + anchorPoint.x: 0 + anchorPoint.y: height/2 + sourceItem: Text { + color: "grey" + text: "5nm" + } + visible: rangeGroup.groupVisible + } + MapQuickItem { + id: text10nm + coordinate { + latitude: position.latitude + longitude: position.longitude + (10/60)/Math.cos(Math.abs(position.latitude)*Math.PI/180) + } + anchorPoint.x: 0 + anchorPoint.y: height/2 + sourceItem: Text { + color: "grey" + text: "10nm" + } + visible: rangeGroup.groupVisible + } + MapQuickItem { + id: text15nm + coordinate { + latitude: position.latitude + longitude: position.longitude + (15/60)/Math.cos(Math.abs(position.latitude)*Math.PI/180) + } + anchorPoint.x: 0 + anchorPoint.y: height/2 + sourceItem: Text { + color: "grey" + text: "15nm" + } + visible: rangeGroup.groupVisible + } + } + + MapQuickItem { + id: airport + anchorPoint.x: image.width/2 + anchorPoint.y: image.height/2 + coordinate: position + zoomLevel: airportZoomLevel + sourceItem: Grid { + columns: 1 + Grid { + horizontalItemAlignment: Grid.AlignHCenter + layer.enabled: smoothing + layer.smooth: smoothing + Image { + id: image + source: airportImage + visible: !lightIcons + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: (mouse) => { + if (mouse.button === Qt.RightButton) { + showRangeItem.visible = !rangeGroup.groupVisible + hideRangeItem.visible = rangeGroup.groupVisible + menuItems.clear() + var scanners = airportModel.getFreqScanners() + for (var i = 0; i < scanners.length; i++) { + menuItems.append({ + text: "Send to Frequency Scanner " + scanners[i], + airport: index, + scanner: scanners[i] + }) + } + contextMenu.popup() + } + } + onDoubleClicked: (mouse) => { + rangeGroup.groupVisible = !rangeGroup.groupVisible + } + + ListModel { + id: menuItems + } + + Menu { + id: contextMenu + MenuItem { + id: showRangeItem + text: "Show range rings" + onTriggered: rangeGroup.groupVisible = true + height: visible ? implicitHeight : 0 + } + MenuItem { + id: hideRangeItem + text: "Hide range rings" + onTriggered: rangeGroup.groupVisible = false + height: visible ? implicitHeight : 0 + } + Instantiator { + model: menuItems + MenuItem { + text: model.text + onTriggered: airportModel.sendToFreqScanner(model.airport, model.scanner) + } + onObjectAdded: function(index, object) { + contextMenu.insertItem(index, object) + } + onObjectRemoved: function(index, object) { + contextMenu.removeItem(object) + } + } + } + } + } + MultiEffect { + width: image.width + height: image.height + source: image + brightness: 1.0 + colorization: 1.0 + colorizationColor: "#c0ffffff" + visible: lightIcons + } + Rectangle { + id: bubble + color: bubbleColour + border.width: 1 + width: text.width + 5 + height: text.height + 5 + radius: 5 + Text { + id: text + anchors.centerIn: parent + text: airportData + } + MouseArea { + anchors.fill: parent + onClicked: (mouse) => { + if (showFreq) { + var freqIdx = Math.floor((mouse.y-5)/((height-10)/airportDataRows)) + if (freqIdx == 0) { + showFreq = false + } + } else { + showFreq = true + } + } + onDoubleClicked: (mouse) => { + if (showFreq) { + var freqIdx = Math.floor((mouse.y-5)/((height-10)/airportDataRows)) + if (freqIdx != 0) { + selectedFreq = freqIdx - 1 + } + } + } + } + } + } + } + } + } + } + +} diff --git a/plugins/channelrx/demodapt/CMakeLists.txt b/plugins/channelrx/demodapt/CMakeLists.txt index 16a76e061e..168e204635 100644 --- a/plugins/channelrx/demodapt/CMakeLists.txt +++ b/plugins/channelrx/demodapt/CMakeLists.txt @@ -35,7 +35,7 @@ if(NOT SERVER_MODE) aptdemodsettingsdialog.ui aptdemodselectdialog.cpp aptdemodselectdialog.ui - icons.qrc + aptdemodicons.qrc ) set(demodapt_HEADERS ${demodapt_HEADERS} @@ -55,9 +55,15 @@ else() set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) endif() -add_library(${TARGET_NAME} SHARED - ${demodapt_SOURCES} -) +if(NOT Qt6_FOUND) + add_library(${TARGET_NAME} ${demodapt_SOURCES}) +else() + qt_add_plugin(${TARGET_NAME} CLASS_NAME APTDemodPlugin ${demodapt_SOURCES}) +endif() + +if(NOT BUILD_SHARED_LIBS) + set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME}) +endif() if(APT_EXTERNAL) add_dependencies(${TARGET_NAME} apt) @@ -67,7 +73,7 @@ if(SGP4_EXTERNAL) add_dependencies(${TARGET_NAME} sgp4) endif() -target_link_libraries(${TARGET_NAME} +target_link_libraries(${TARGET_NAME} PRIVATE Qt::Core ${TARGET_LIB} sdrbase diff --git a/plugins/channelrx/demodapt/icons.qrc b/plugins/channelrx/demodapt/aptdemodicons.qrc similarity index 100% rename from plugins/channelrx/demodapt/icons.qrc rename to plugins/channelrx/demodapt/aptdemodicons.qrc diff --git a/plugins/channelrx/radioastronomy/CMakeLists.txt b/plugins/channelrx/radioastronomy/CMakeLists.txt index f378b67066..8834d3bece 100644 --- a/plugins/channelrx/radioastronomy/CMakeLists.txt +++ b/plugins/channelrx/radioastronomy/CMakeLists.txt @@ -33,7 +33,7 @@ if(NOT SERVER_MODE) radioastronomycalibrationdialog.ui radioastronomysensordialog.cpp radioastronomysensordialog.ui - icons.qrc + radioastronomyicons.qrc ) set(radioastronomy_HEADERS ${radioastronomy_HEADERS} @@ -53,11 +53,17 @@ else() set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) endif() -add_library(${TARGET_NAME} SHARED - ${radioastronomy_SOURCES} -) +if(NOT Qt6_FOUND) + add_library(${TARGET_NAME} ${radioastronomy_SOURCES}) +else() + qt_add_plugin(${TARGET_NAME} CLASS_NAME RadioAstronomyPlugin ${radioastronomy_SOURCES}) +endif() + +if(NOT BUILD_SHARED_LIBS) + set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME}) +endif() -target_link_libraries(${TARGET_NAME} +target_link_libraries(${TARGET_NAME} PRIVATE Qt::Core ${TARGET_LIB} sdrbase diff --git a/plugins/channelrx/radioastronomy/radioastronomy.cpp b/plugins/channelrx/radioastronomy/radioastronomy.cpp index db300c5a45..999adae019 100644 --- a/plugins/channelrx/radioastronomy/radioastronomy.cpp +++ b/plugins/channelrx/radioastronomy/radioastronomy.cpp @@ -382,6 +382,7 @@ void RadioAstronomy::startCal(bool hot) // Execute command to enable calibration if (!m_settings.m_startCalCommand.isEmpty()) { +#if QT_CONFIG(process) #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) QStringList allArgs = m_settings.m_startCalCommand.split(" ", Qt::SkipEmptyParts); #else @@ -390,6 +391,9 @@ void RadioAstronomy::startCal(bool hot) QString program = allArgs[0]; allArgs.pop_front(); QProcess::startDetached(program, allArgs); +#else + qWarning() << "RadioAstronomy::startCal: QProcess not supported. Can't run: " << m_settings.m_startCalCommand; +#endif } // Start calibration after requested delay @@ -423,6 +427,7 @@ void RadioAstronomy::calComplete(MsgCalComplete* report) // Execute command to disable calibration if (!m_settings.m_stopCalCommand.isEmpty()) { +#if QT_CONFIG(process) #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) QStringList allArgs = m_settings.m_stopCalCommand.split(" ", Qt::SkipEmptyParts); #else @@ -431,6 +436,9 @@ void RadioAstronomy::calComplete(MsgCalComplete* report) QString program = allArgs[0]; allArgs.pop_front(); QProcess::startDetached(program, allArgs); +#else + qWarning() << "RadioAstronomy::calComplete: QProcess not supported. Can't run: " << m_settings.m_startCalCommand; +#endif } // Send calibration result to GUI diff --git a/plugins/channelrx/radioastronomy/icons.qrc b/plugins/channelrx/radioastronomy/radioastronomyicons.qrc similarity index 100% rename from plugins/channelrx/radioastronomy/icons.qrc rename to plugins/channelrx/radioastronomy/radioastronomyicons.qrc diff --git a/plugins/feature/map/CMakeLists.txt b/plugins/feature/map/CMakeLists.txt index b43cfc2703..45c5d9a1e3 100644 --- a/plugins/feature/map/CMakeLists.txt +++ b/plugins/feature/map/CMakeLists.txt @@ -41,7 +41,7 @@ if(NOT SERVER_MODE) set(map_SOURCES ${map_SOURCES} mapgui.cpp - ${CMAKE_CURRENT_BINARY_DIR}/mapgui.ui + #${CMAKE_CURRENT_BINARY_DIR}/mapgui.ui maplocationdialog.cpp maplocationdialog.ui mapmaidenheaddialog.cpp @@ -61,9 +61,9 @@ if(NOT SERVER_MODE) cesiuminterface.cpp czml.cpp map.qrc - icons.qrc + mapicons.qrc cesium.qrc - data.qrc + mapdata.qrc ) set(map_HEADERS ${map_HEADERS} @@ -91,7 +91,7 @@ if(NOT SERVER_MODE) set(TARGET_LIB ${TARGET_LIB} Qt::WebEngine Qt::WebEngineCore Qt::WebEngineWidgets) elseif(Qt${QT_DEFAULT_MAJOR_VERSION}WebEngineCore_FOUND) set(TARGET_LIB ${TARGET_LIB} Qt::SvgWidgets Qt::WebEngineCore Qt::WebEngineWidgets) - elseif(ANDROID) + else() set(TARGET_LIB ${TARGET_LIB} Qt::SvgWidgets) endif() else() @@ -101,11 +101,17 @@ else() set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) endif() -add_library(${TARGET_NAME} SHARED - ${map_SOURCES} -) +if(NOT Qt6_FOUND) + add_library(${TARGET_NAME} ${map_SOURCES}) +else() + qt_add_plugin(${TARGET_NAME} CLASS_NAME MapPlugin ${map_SOURCES}) +endif() + +if(NOT BUILD_SHARED_LIBS) + set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME}) +endif() -target_link_libraries(${TARGET_NAME} +target_link_libraries(${TARGET_NAME} PRIVATE Qt::Core ${TARGET_LIB} sdrbase diff --git a/plugins/feature/map/map.qrc b/plugins/feature/map/map.qrc index b0df123cec..7a0eeaa05b 100644 --- a/plugins/feature/map/map.qrc +++ b/plugins/feature/map/map.qrc @@ -8,6 +8,7 @@ map/antennadab.png map/antennafm.png map/antennaam.png + map/antennaangel.png map/antennakiwi.png map/antennaspyserver.png map/ionosonde.png diff --git a/plugins/feature/map/map/antennaangel.png b/plugins/feature/map/map/antennaangel.png new file mode 100644 index 0000000000000000000000000000000000000000..4d28e8c29902887dc7577d346c3326aac5ac9b15 GIT binary patch literal 3857 zcma)930xFq8{Y-ND@qZ(2w2xZ1ZQ`4_MRlJMObA)fkaD)+1XikblDkq1{M%?@yL+) zR76uz$`tb~3vaNX&x%yQ$fHt`lrJIu1Ot!q;Cp8|q@up|_uFOWdH>J-W4^ zyEvm}7I|iL(87<(k1RZ%>c8aVn5v2mv$u8{A3e=y)62(<(i|IMJF$3KiORO`TI;AQ zQT~m4&krfRVK_P`a8#~l7kd5LTGC?%5njU%|FvMnI8EW?lx^4V&Q?yCT409AOG64K zrtBMeM^JLe_3pzuUPsA)7kJg^zup^kaeqOgo9uAs0n_|~&gKKBYioSJD#~zv71DiN z<9FHJQY{A!Hpm3uAzJCE9b}ka(U6# zF715V`-Jbubjg^HCcSpgN8Co=PWYhVfZgNsoNaCO(eKR3J+toCj>a#UxR9CO{rIz& z&(vnk@|9lFr>{)CdU>OPTic{$#%s}Z0QC2z)&^+GMkSrR*7Z9vKPo$BSU}0OuXF>sK2o@&Eb+C?(AWUR* zj+IEriA}_F7T{`wFys}%)GQPbq!TPA$VxX`7&I$b=-@@cH76De1r7+iAXpg285GO` zeG)-g34vN9fp8c`1WL8YpvR;JOgcq?z=%{VLBtX%1j|uafy&f^o{tcivl@(Oyk=UD zF>n_wG_fp=ip4gYO=OdbC~KNnqE@TLFd{|}2p}LP+rna5kcFAp%b+0`+)C0cNm&FO zBc`V^*kB=WwL6A%TBqwHwlF=J0yz_BVYFBxg2n0STwo3~!$xKTB z7%Ibx6OoyOg`L=|&dp7qHWx%1nNB;x0Ez80V!-<_bcWUJI5*&8!c3$CG6wi0>B9oO zKJb9<^qQtk6iYEC>M!7Z$Bu}5m9#XA%YcccL*W@*I<%T#A(uteK;fhT zbzI_7gplY}Fr?JO21urtOCh};mqKz3Rv8trgurD6&Lqd9wJ(#$5}}*L72I}KOBz%@E9;yA(tX5$SA`I z;0KOFYK)LUN*N9-RZ0Uc$BjY(*A!^jOl`0b5y3sTGtC%lq^#*+AW4gXvN1jKL^7R7 zU@@-f5(OfY$>j=}N{+xvrMd?(o3JvV)j2W=EJ6^Wz<{IE02KyGNTy?HgqXIZIi#F{ zKS+V+XoQu(Sjw76QRZNwW7Bg~j(EGz2o1&(zyOTM9Q8&LB@$GsLM7_gx=}jHKpM0A zqvVi8mMDQyM2X53L9hgcdkA%4Z5S{X`@i7621O$%Gi3!PfD2NgfNKmC6almX#?3fL z3^)1R#f>Hz5J`5=E=eF3_FS1sfn$G8mPqgyMhX`#_%lvv%%|w9h^$?SMt=hW#O+?qxr-cf|-0 zxk&lv*!ty_3r5Us0jj}F?v&QM?6FB=fEPqD!=ZOc8U52%0YyU2s-+{QjiE6p|O~{~WGf7x` zjDrk15-}j)nXqT7|5EAMxkD#{qO-wfGqG_t%fP1ogmCD^kT_vsr~#epcjl;lzb7+r z%OL`fd+xIDMFZUQy{ZrvFp^gABJ$?_@3-)HgJQLsutZbdg)KT$a-_#sOFuZExZCl? z`v=}Ky}kN~NBjcZZ~ol{+oMMdcMp2(l$;+VA0C#pT3obpxLd|7x9>nqTT_k(EF2dors$UMru}Bx)Mc?ny6NdEyqIf9-fnrc?Wi@0FJN@Q?C? z@`mRPw+GoXszy~+RMl5SRUP&@ksK4{Ww$hWH)S>7yXY30xI{L|UR`v5pPd=xOU6D_@;YOq^23#sM`GkQublYs=UQ^K2#;QK6f2C?O8Z|JkPamqHp0BW_4q= z%&urExDvcS^d5Tt+Q<%XN!ipSYsjdm)5cUg>^!-C!xhT!ta&n4{+jE&I`(0(i$^oN zseZSQ|Dn;x20e^ySh2Ib%BM-6T6px69A0$os-jOS#$9j@{kf{R_^S8uQeK0!qjgh7 zy?x)PlDT|U*w{@8D|BsB+Jnz&=oZhS*qqkR(!3)N>z3Nj*#EnN2~B7ocd$BPyV8C( zx6$bcKk17@&@T=o!+JjdkcNpzHa}Hp$FFmcok-NC9^N{O>4H@ zUQ-XP@X9xzT4moDaBEHF{gut9zW*&G)i~`~>!+f1O6U5L@7+HiGoJp%SiFi=CW0thSBg;;k zAHyTPom24p-X?z5`u076JJRrzlwV=}zKQa;f4kM(RSG8s)*badd}X@XZ_2x~_vl^R o4-%gij(PH#`|vx|hRROy2(Ph9;hY(P-2X?~$XLyX;i=312jy49@Bjb+ literal 0 HcmV?d00001 diff --git a/plugins/feature/map/data.qrc b/plugins/feature/map/mapdata.qrc similarity index 100% rename from plugins/feature/map/data.qrc rename to plugins/feature/map/mapdata.qrc diff --git a/plugins/feature/map/mapguinowebengine.ui b/plugins/feature/map/mapguinowebengine.ui index dc455fc857..ec09d2bff8 100644 --- a/plugins/feature/map/mapguinowebengine.ui +++ b/plugins/feature/map/mapguinowebengine.ui @@ -6,7 +6,7 @@ 0 0 - 491 + 1031 507 @@ -39,7 +39,7 @@ 0 0 - 480 + 751 41 @@ -171,6 +171,20 @@ + + + + + + + + :/map/icons/layers.png:/map/icons/layers.png + + + QToolButton::InstantPopup + + + @@ -351,6 +365,20 @@ + + + + Save to .kml + + + + + + + :/save.png:/save.png + + + @@ -379,6 +407,71 @@ + + + + + 34 + 0 + + + + 100% + + + + + + + Display NASA GIBS data + + + ^ + + + + :/map/icons/earthsat.png:/map/icons/earthsat.png + + + true + + + true + + + + + + + + 24 + 24 + + + + NASA GIBS image opacity (3D only) + + + 100 + + + 100 + + + + + + + + 200 + 0 + + + + NASA GIBS data + + + diff --git a/plugins/feature/map/icons.qrc b/plugins/feature/map/mapicons.qrc similarity index 100% rename from plugins/feature/map/icons.qrc rename to plugins/feature/map/mapicons.qrc diff --git a/plugins/feature/map/mapitem.cpp b/plugins/feature/map/mapitem.cpp index 644edebc3f..4cb0438075 100644 --- a/plugins/feature/map/mapitem.cpp +++ b/plugins/feature/map/mapitem.cpp @@ -15,8 +15,6 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include - #include "mapitem.h" MapItem::MapItem(const QObject *sourcePipe, const QString &group, MapSettings::MapItemSettings *itemSettings, SWGSDRangel::SWGMapItem *mapItem) : diff --git a/plugins/feature/map/maptileserver.h b/plugins/feature/map/maptileserver.h index f1b4caf224..8652076870 100644 --- a/plugins/feature/map/maptileserver.h +++ b/plugins/feature/map/maptileserver.h @@ -181,7 +181,9 @@ class MapTileServer : public QTcpServer } QNetworkReply *reply = m_manager.get(request); +#ifndef QT_NO_OPENSSL connect(reply, &QNetworkReply::sslErrors, this, &MapTileServer::sslErrors); +#endif //qDebug() << "MapTileServer: Downloading from " << url; return reply; } @@ -407,6 +409,7 @@ private slots: m_replies.remove(reply); } +#ifndef QT_NO_OPENSSL void sslErrors(const QList &sslErrors) { for (const QSslError &error : sslErrors) @@ -425,6 +428,7 @@ private slots: #endif } } +#endif }; diff --git a/plugins/feature/satellitetracker/satellitetrackergui.cpp b/plugins/feature/satellitetracker/satellitetrackergui.cpp index 8f3c70df71..4e9641044d 100644 --- a/plugins/feature/satellitetracker/satellitetrackergui.cpp +++ b/plugins/feature/satellitetracker/satellitetrackergui.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -334,7 +333,9 @@ SatelliteTrackerGUI::SatelliteTrackerGUI(PluginAPI* pluginAPI, FeatureUISet *fea connect(ui->satTable->horizontalHeader(), SIGNAL(sectionMoved(int, int, int)), SLOT(satTable_sectionMoved(int, int, int))); connect(ui->satTable->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), SLOT(satTable_sectionResized(int, int, int))); +#ifdef QT_TEXTTOSPEECH_FOUND m_speech = new QTextToSpeech(this); +#endif displaySettings(); applySettings(true); @@ -441,16 +442,26 @@ void SatelliteTrackerGUI::aos(const QString &speech) // Call plotChart() to start the periodic updates with sat position in polar chart plotChart(); // Give speech notification of pass - if (!speech.isEmpty()) { + if (!speech.isEmpty()) + { +#ifdef QT_TEXTTOSPEECH_FOUND m_speech->say(speech); +#else + qWarning() << "SatelliteTrackerGUI::aos: No TextToSpeech: " << speech; +#endif } } void SatelliteTrackerGUI::los(const QString &speech) { // Give speech notification of end of pass - if (!speech.isEmpty()) { + if (!speech.isEmpty()) + { +#ifdef QT_TEXTTOSPEECH_FOUND m_speech->say(speech); +#else + qWarning() << "SatelliteTrackerGUI::los: No TextToSpeech: " << speech; +#endif } } diff --git a/plugins/feature/satellitetracker/satellitetrackergui.h b/plugins/feature/satellitetracker/satellitetrackergui.h index 09a128e438..a38f9c0284 100644 --- a/plugins/feature/satellitetracker/satellitetrackergui.h +++ b/plugins/feature/satellitetracker/satellitetrackergui.h @@ -92,7 +92,9 @@ class SatelliteTrackerGUI : public FeatureGUI { QDateTime m_nextTargetLOS; bool m_geostationarySatVisible; +#ifdef QT_TEXTTOSPEECH_FOUND QTextToSpeech *m_speech; +#endif QMenu *menu; // Column select context menu enum SatCol { diff --git a/plugins/feature/satellitetracker/satellitetrackersgp4.cpp b/plugins/feature/satellitetracker/satellitetrackersgp4.cpp index c8d6503485..33022dc0b9 100644 --- a/plugins/feature/satellitetracker/satellitetrackersgp4.cpp +++ b/plugins/feature/satellitetracker/satellitetrackersgp4.cpp @@ -65,7 +65,11 @@ void getGroundTrack(QDateTime dateTime, // For 3D map, we want to quantize to minutes, so we replace previous // position data, rather than insert additional positions alongside the old // which can result is the camera view jumping around +#if QT_CONFIG(timezone) dateTime = QDateTime(dateTime.date(), QTime(dateTime.time().hour(), dateTime.time().minute()), dateTime.timeZone()); +#else + dateTime = QDateTime(dateTime.date(), QTime(dateTime.time().hour(), dateTime.time().minute())); +#endif // Note 2D map doesn't support paths wrapping around Earth several times // So we just have a slight overlap here, with the future track being longer diff --git a/plugins/feature/satellitetracker/satellitetrackerworker.cpp b/plugins/feature/satellitetracker/satellitetrackerworker.cpp index 680af04405..9b6db8e248 100644 --- a/plugins/feature/satellitetracker/satellitetrackerworker.cpp +++ b/plugins/feature/satellitetracker/satellitetrackerworker.cpp @@ -668,6 +668,7 @@ void SatelliteTrackerWorker::executeCommand(const QString &command, const QStrin { if (!command.isEmpty()) { +#if QT_CONFIG(process) // Replace variables QString cmd = substituteVariables(command, satelliteName); QStringList allArgs = QProcess::splitCommand(cmd); @@ -675,6 +676,9 @@ void SatelliteTrackerWorker::executeCommand(const QString &command, const QStrin QString program = allArgs[0]; allArgs.pop_front(); QProcess::startDetached(program, allArgs); +#else + qWarning() << "SatelliteTrackerWorker::executeCommand: QProcess not supported. Can't run: " << command; +#endif } } diff --git a/plugins/feature/sid/CMakeLists.txt b/plugins/feature/sid/CMakeLists.txt index 70397716cd..0de7854b7d 100644 --- a/plugins/feature/sid/CMakeLists.txt +++ b/plugins/feature/sid/CMakeLists.txt @@ -29,7 +29,7 @@ if(NOT SERVER_MODE) sidsettingsdialog.ui sidaddchannelsdialog.cpp sidaddchannelsdialog.ui - icons.qrc + sidicons.qrc ) set(sid_HEADERS ${sid_HEADERS} @@ -49,11 +49,17 @@ else() set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) endif() -add_library(${TARGET_NAME} SHARED - ${sid_SOURCES} -) +if(NOT Qt6_FOUND) + add_library(${TARGET_NAME} ${sid_SOURCES}) +else() + qt_add_plugin(${TARGET_NAME} CLASS_NAME SIDPlugin ${sid_SOURCES}) +endif() + +if(NOT BUILD_SHARED_LIBS) + set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME}) +endif() -target_link_libraries(${TARGET_NAME} +target_link_libraries(${TARGET_NAME} PRIVATE Qt::Core ${TARGET_LIB} sdrbase diff --git a/plugins/feature/sid/readme.md b/plugins/feature/sid/readme.md index 94693fd246..1a1a441ccc 100644 --- a/plugins/feature/sid/readme.md +++ b/plugins/feature/sid/readme.md @@ -211,11 +211,11 @@ When clicked, the X-axis is set 1 day later than the current setting, at the sam

27: Start Time

-Displays/sets the current start time of the chart (X-axis minimum). It's possible to scroll through hours/days/months by clicking on the relevant segment and using the mouse scroll wheel. +Displays/sets the current local start time of the chart (X-axis minimum). It's possible to scroll through hours/days/months by clicking on the relevant segment and using the mouse scroll wheel.

28: End Time

-Displays/sets the current end time of the chart (X-axis maximum). It's possible to scroll through hours/days/months by clicking on the relevant segment and using the mouse scroll wheel. +Displays/sets the current local end time of the chart (X-axis maximum). It's possible to scroll through hours/days/months by clicking on the relevant segment and using the mouse scroll wheel.

29: Min

@@ -231,7 +231,7 @@ When checked, the latest SDO imagery is displayed. When unchecked, you can enter

32: Date Time

-Specifies the date and time for which SDO imagery should be displayed. Images are updated every 15 minutes. The date and time can also be set by clicking on the chart. +Specifies the local date and time for which SDO imagery should be displayed. Images are updated every 15 minutes. The date and time can also be set by clicking on the chart.

33: Map

diff --git a/plugins/feature/sid/sidgui.cpp b/plugins/feature/sid/sidgui.cpp index f6fb0637ca..69c7bd3c8f 100644 --- a/plugins/feature/sid/sidgui.cpp +++ b/plugins/feature/sid/sidgui.cpp @@ -2035,7 +2035,15 @@ void SIDGUI::on_showPaths_clicked() { // Get position of device, defaulting to My Position QGeoCoordinate rxPosition; - if (!ChannelWebAPIUtils::getDevicePosition(deviceSetIndex, rxPosition)) + float latitude, longitude, altitude; + + if (ChannelWebAPIUtils::getDevicePosition(deviceSetIndex, latitude, longitude, altitude)) + { + rxPosition.setLatitude(latitude); + rxPosition.setLongitude(longitude); + rxPosition.setAltitude(altitude); + } + else { rxPosition.setLatitude(MainCore::instance()->getSettings().getLatitude()); rxPosition.setLongitude(MainCore::instance()->getSettings().getLongitude()); diff --git a/plugins/feature/sid/icons.qrc b/plugins/feature/sid/sidicons.qrc similarity index 100% rename from plugins/feature/sid/icons.qrc rename to plugins/feature/sid/sidicons.qrc diff --git a/plugins/feature/vorlocalizer/CMakeLists.txt b/plugins/feature/vorlocalizer/CMakeLists.txt index 894f5286c5..7a8221e626 100644 --- a/plugins/feature/vorlocalizer/CMakeLists.txt +++ b/plugins/feature/vorlocalizer/CMakeLists.txt @@ -28,8 +28,8 @@ if(NOT SERVER_MODE) ${vor_SOURCES} vorlocalizergui.cpp vorlocalizergui.ui - map.qrc - icons.qrc + vorlocalizermap.qrc + vorlocalizericons.qrc ) set(vor_HEADERS ${vor_HEADERS} @@ -47,11 +47,17 @@ else() set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) endif() -add_library(${TARGET_NAME} SHARED - ${vor_SOURCES} -) +if(NOT Qt6_FOUND) + add_library(${TARGET_NAME} ${vor_SOURCES}) +else() + qt_add_plugin(${TARGET_NAME} CLASS_NAME VORLocalizerPlugin ${vor_SOURCES}) +endif() + +if(NOT BUILD_SHARED_LIBS) + set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME}) +endif() -target_link_libraries(${TARGET_NAME} +target_link_libraries(${TARGET_NAME} PRIVATE Qt::Core ${TARGET_LIB} sdrbase diff --git a/plugins/feature/vorlocalizer/icons.qrc b/plugins/feature/vorlocalizer/vorlocalizericons.qrc similarity index 100% rename from plugins/feature/vorlocalizer/icons.qrc rename to plugins/feature/vorlocalizer/vorlocalizericons.qrc diff --git a/plugins/feature/vorlocalizer/map.qrc b/plugins/feature/vorlocalizer/vorlocalizermap.qrc similarity index 100% rename from plugins/feature/vorlocalizer/map.qrc rename to plugins/feature/vorlocalizer/vorlocalizermap.qrc diff --git a/sdrbase/channel/channelwebapiutils.cpp b/sdrbase/channel/channelwebapiutils.cpp index 4fb10f71a5..f78f06841c 100644 --- a/sdrbase/channel/channelwebapiutils.cpp +++ b/sdrbase/channel/channelwebapiutils.cpp @@ -369,6 +369,7 @@ bool ChannelWebAPIUtils::setCenterFrequency(unsigned int deviceIndex, double fre deviceSettingsResponse.init(); deviceSettingsResponse.fromJsonObject(*jsonObj); SWGSDRangel::SWGErrorResponse errorResponse2; + delete jsonObj; DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); if (source) { @@ -910,7 +911,9 @@ bool ChannelWebAPIUtils::getFrequencyOffset(unsigned int deviceIndex, int channe } jsonObj = channelSettingsResponse.asJsonObject(); - if (WebAPIUtils::getSubObjectDouble(*jsonObj, "inputFrequencyOffset", offsetD)) + bool result = WebAPIUtils::getSubObjectDouble(*jsonObj, "inputFrequencyOffset", offsetD); + delete jsonObj; + if (result) { offset = (int)offsetD; return true; @@ -946,6 +949,7 @@ bool ChannelWebAPIUtils::setFrequencyOffset(unsigned int deviceIndex, int channe keys.append("inputFrequencyOffset"); channelSettingsResponse.init(); channelSettingsResponse.fromJsonObject(*jsonObj); + delete jsonObj; httpRC = channel->webapiSettingsPutPatch(false, keys, channelSettingsResponse, errorResponse); if (httpRC/100 != 2) { @@ -956,6 +960,7 @@ bool ChannelWebAPIUtils::setFrequencyOffset(unsigned int deviceIndex, int channe return true; } + delete jsonObj; } return false; } @@ -986,6 +991,7 @@ bool ChannelWebAPIUtils::setAudioMute(unsigned int deviceIndex, int channelIndex keys.append("audioMute"); channelSettingsResponse.init(); channelSettingsResponse.fromJsonObject(*jsonObj); + delete jsonObj; httpRC = channel->webapiSettingsPutPatch(false, keys, channelSettingsResponse, errorResponse); if (httpRC / 100 != 2) { @@ -996,6 +1002,7 @@ bool ChannelWebAPIUtils::setAudioMute(unsigned int deviceIndex, int channelIndex return true; } + delete jsonObj; } return false; } @@ -1120,7 +1127,9 @@ bool ChannelWebAPIUtils::getDeviceSetting(unsigned int deviceIndex, const QStrin if (getDeviceSettings(deviceIndex, deviceSettingsResponse, deviceSet)) { QJsonObject *jsonObj = deviceSettingsResponse.asJsonObject(); - return WebAPIUtils::getSubObjectInt(*jsonObj, setting, value); + bool result = WebAPIUtils::getSubObjectInt(*jsonObj, setting, value); + delete jsonObj; + return result; } else { @@ -1136,7 +1145,9 @@ bool ChannelWebAPIUtils::getDeviceReportValue(unsigned int deviceIndex, const QS { // Get value of requested key QJsonObject *jsonObj = deviceReport.asJsonObject(); - if (WebAPIUtils::getSubObjectString(*jsonObj, key, value)) + bool result = WebAPIUtils::getSubObjectString(*jsonObj, key, value); + delete jsonObj; + if (result) { // Done return true; @@ -1158,7 +1169,9 @@ bool ChannelWebAPIUtils::getDeviceReportList(unsigned int deviceIndex, const QSt { // Get value of requested key QJsonObject *jsonObj = deviceReport.asJsonObject(); - if (WebAPIUtils::getSubObjectIntList(*jsonObj, key, subKey, values)) + bool result = WebAPIUtils::getSubObjectIntList(*jsonObj, key, subKey, values); + delete jsonObj; + if (result) { // Done return true; @@ -1173,29 +1186,27 @@ bool ChannelWebAPIUtils::getDeviceReportList(unsigned int deviceIndex, const QSt } -bool ChannelWebAPIUtils::getDevicePosition(unsigned int deviceIndex, QGeoCoordinate& position) +bool ChannelWebAPIUtils::getDevicePosition(unsigned int deviceIndex, float& latitude, float& longitude, float& altitude) { SWGSDRangel::SWGDeviceReport deviceReport; if (getDeviceReport(deviceIndex, deviceReport)) { QJsonObject *jsonObj = deviceReport.asJsonObject(); - double latitude, longitude, altitude; - - if (WebAPIUtils::getSubObjectDouble(*jsonObj, "latitude", latitude) - && WebAPIUtils::getSubObjectDouble(*jsonObj, "longitude", longitude) - && WebAPIUtils::getSubObjectDouble(*jsonObj, "altitude", altitude)) - { - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAltitude(altitude); - // Done - return true; - } - else + double latitudeDouble, longitudeDouble, altitudeDouble; + bool result = WebAPIUtils::getSubObjectDouble(*jsonObj, "latitude", latitudeDouble) + && WebAPIUtils::getSubObjectDouble(*jsonObj, "longitude", longitudeDouble) + && WebAPIUtils::getSubObjectDouble(*jsonObj, "altitude", altitudeDouble); + delete jsonObj; + if (result) { - //qWarning("ChannelWebAPIUtils::getDevicePosition: no latitude/longitude/altitude in device report"); - return false; + if (!std::isnan(latitudeDouble) && !std::isnan(longitudeDouble) && !std::isnan(altitudeDouble)) + { + latitude = (float) latitudeDouble; + longitude = (float) longitudeDouble; + altitude = (float) altitudeDouble; + return true; + } } } return false; @@ -1305,6 +1316,7 @@ bool ChannelWebAPIUtils::patchDeviceSetting(unsigned int deviceIndex, const QStr deviceSettingsResponse.init(); deviceSettingsResponse.fromJsonObject(*jsonObj); SWGSDRangel::SWGErrorResponse errorResponse2; + delete jsonObj; DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); @@ -1324,6 +1336,7 @@ bool ChannelWebAPIUtils::patchDeviceSetting(unsigned int deviceIndex, const QStr } else { + delete jsonObj; qWarning("ChannelWebAPIUtils::patchDeviceSetting: no key %s in device settings", qPrintable(setting)); return false; } @@ -1354,6 +1367,7 @@ bool ChannelWebAPIUtils::patchFeatureSetting(unsigned int featureSetIndex, unsig featureSettingsResponse.init(); featureSettingsResponse.fromJsonObject(*jsonObj); SWGSDRangel::SWGErrorResponse errorResponse2; + delete jsonObj; httpRC = feature->webapiSettingsPutPatch(false, featureSettingsKeys, featureSettingsResponse, *errorResponse2.getMessage()); @@ -1371,6 +1385,7 @@ bool ChannelWebAPIUtils::patchFeatureSetting(unsigned int featureSetIndex, unsig } else { + delete jsonObj; qWarning("ChannelWebAPIUtils::patchFeatureSetting: no key %s in feature settings", qPrintable(setting)); return false; } @@ -1401,6 +1416,7 @@ bool ChannelWebAPIUtils::patchFeatureSetting(unsigned int featureSetIndex, unsig featureSettingsResponse.init(); featureSettingsResponse.fromJsonObject(*jsonObj); SWGSDRangel::SWGErrorResponse errorResponse2; + delete jsonObj; httpRC = feature->webapiSettingsPutPatch(false, featureSettingsKeys, featureSettingsResponse, *errorResponse2.getMessage()); @@ -1418,6 +1434,7 @@ bool ChannelWebAPIUtils::patchFeatureSetting(unsigned int featureSetIndex, unsig } else { + delete jsonObj; qWarning("ChannelWebAPIUtils::patchFeatureSetting: no key %s in feature settings", qPrintable(setting)); return false; } @@ -1480,6 +1497,7 @@ bool ChannelWebAPIUtils::patchFeatureSetting(unsigned int featureSetIndex, unsig featureSettingsResponse.init(); featureSettingsResponse.fromJsonObject(*jsonObj); SWGSDRangel::SWGErrorResponse errorResponse2; + delete jsonObj; httpRC = feature->webapiSettingsPutPatch(false, featureSettingsKeys, featureSettingsResponse, *errorResponse2.getMessage()); @@ -1519,6 +1537,7 @@ bool ChannelWebAPIUtils::patchChannelSetting(ChannelAPI *channel, const QString channelSettingsResponse.init(); channelSettingsResponse.fromJsonObject(*jsonObj); SWGSDRangel::SWGErrorResponse errorResponse2; + delete jsonObj; httpRC = channel->webapiSettingsPutPatch(false, channelSettingsKeys, channelSettingsResponse, *errorResponse2.getMessage()); @@ -1536,6 +1555,7 @@ bool ChannelWebAPIUtils::patchChannelSetting(ChannelAPI *channel, const QString } else { + delete jsonObj; qWarning("ChannelWebAPIUtils::patchChannelSetting: no key %s in channel settings", qPrintable(setting)); return false; } @@ -1631,6 +1651,7 @@ bool ChannelWebAPIUtils::patchChannelSetting(unsigned int deviceSetIndex, unsign channelSettingsResponse.init(); channelSettingsResponse.fromJsonObject(*jsonObj); SWGSDRangel::SWGErrorResponse errorResponse2; + delete jsonObj; httpRC = channel->webapiSettingsPutPatch(false, channelSettingsKeys, channelSettingsResponse, *errorResponse2.getMessage()); @@ -1660,7 +1681,9 @@ bool ChannelWebAPIUtils::getFeatureSetting(unsigned int featureSetIndex, unsign if (getFeatureSettings(featureSetIndex, featureIndex, featureSettingsResponse, feature)) { QJsonObject *jsonObj = featureSettingsResponse.asJsonObject(); - return WebAPIUtils::getSubObjectInt(*jsonObj, setting, value); + bool result = WebAPIUtils::getSubObjectInt(*jsonObj, setting, value); + delete jsonObj; + return result; } else { @@ -1676,7 +1699,9 @@ bool ChannelWebAPIUtils::getFeatureSetting(unsigned int featureSetIndex, unsign if (getFeatureSettings(featureSetIndex, featureIndex, featureSettingsResponse, feature)) { QJsonObject *jsonObj = featureSettingsResponse.asJsonObject(); - return WebAPIUtils::getSubObjectDouble(*jsonObj, setting, value); + bool result = WebAPIUtils::getSubObjectDouble(*jsonObj, setting, value); + delete jsonObj; + return result; } else { @@ -1692,7 +1717,9 @@ bool ChannelWebAPIUtils::getFeatureSetting(unsigned int featureSetIndex, unsign if (getFeatureSettings(featureSetIndex, featureIndex, featureSettingsResponse, feature)) { QJsonObject *jsonObj = featureSettingsResponse.asJsonObject(); - return WebAPIUtils::getSubObjectString(*jsonObj, setting, value); + bool result = WebAPIUtils::getSubObjectString(*jsonObj, setting, value); + delete jsonObj; + return result; } else { @@ -1708,7 +1735,9 @@ bool ChannelWebAPIUtils::getChannelSetting(unsigned int deviceSetIndex, unsigne if (getChannelSettings(deviceSetIndex, channelIndex, channelSettingsResponse, channel)) { QJsonObject *jsonObj = channelSettingsResponse.asJsonObject(); - return WebAPIUtils::getSubObjectInt(*jsonObj, setting, value); + bool result = WebAPIUtils::getSubObjectInt(*jsonObj, setting, value); + delete jsonObj; + return result; } else { @@ -1724,7 +1753,9 @@ bool ChannelWebAPIUtils::getChannelSetting(unsigned int deviceSetIndex, unsigne if (getChannelSettings(deviceSetIndex, channelIndex, channelSettingsResponse, channel)) { QJsonObject *jsonObj = channelSettingsResponse.asJsonObject(); - return WebAPIUtils::getSubObjectDouble(*jsonObj, setting, value); + bool result = WebAPIUtils::getSubObjectDouble(*jsonObj, setting, value); + delete jsonObj; + return result; } else { @@ -1740,7 +1771,9 @@ bool ChannelWebAPIUtils::getChannelSetting(unsigned int deviceSetIndex, unsigne if (getChannelSettings(deviceSetIndex, channelIndex, channelSettingsResponse, channel)) { QJsonObject *jsonObj = channelSettingsResponse.asJsonObject(); - return WebAPIUtils::getSubObjectString(*jsonObj, setting, value); + bool result = WebAPIUtils::getSubObjectString(*jsonObj, setting, value); + delete jsonObj; + return result; } else { @@ -1756,7 +1789,9 @@ bool ChannelWebAPIUtils::getFeatureReportValue(unsigned int featureSetIndex, uns { // Get value of requested key QJsonObject *jsonObj = featureReport.asJsonObject(); - if (WebAPIUtils::getSubObjectInt(*jsonObj, key, value)) + bool result = WebAPIUtils::getSubObjectInt(*jsonObj, key, value); + delete jsonObj; + if (result) { // Done return true; @@ -1778,7 +1813,9 @@ bool ChannelWebAPIUtils::getFeatureReportValue(unsigned int featureSetIndex, uns { // Get value of requested key QJsonObject *jsonObj = featureReport.asJsonObject(); - if (WebAPIUtils::getSubObjectDouble(*jsonObj, key, value)) + bool result = WebAPIUtils::getSubObjectDouble(*jsonObj, key, value); + delete jsonObj; + if (result) { // Done return true; @@ -1800,7 +1837,9 @@ bool ChannelWebAPIUtils::getFeatureReportValue(unsigned int featureSetIndex, uns { // Get value of requested key QJsonObject *jsonObj = featureReport.asJsonObject(); - if (WebAPIUtils::getSubObjectString(*jsonObj, key, value)) + bool result = WebAPIUtils::getSubObjectString(*jsonObj, key, value); + delete jsonObj; + if (result) { // Done return true; @@ -1823,7 +1862,9 @@ bool ChannelWebAPIUtils::getChannelReportValue(unsigned int deviceIndex, unsigne { // Get value of requested key QJsonObject *jsonObj = channelReport.asJsonObject(); - if (WebAPIUtils::getSubObjectInt(*jsonObj, key, value)) + bool result = WebAPIUtils::getSubObjectInt(*jsonObj, key, value); + delete jsonObj; + if (result) { // Done return true; @@ -1845,7 +1886,9 @@ bool ChannelWebAPIUtils::getChannelReportValue(unsigned int deviceIndex, unsigne { // Get value of requested key QJsonObject *jsonObj = channelReport.asJsonObject(); - if (WebAPIUtils::getSubObjectDouble(*jsonObj, key, value)) + bool result = WebAPIUtils::getSubObjectDouble(*jsonObj, key, value); + delete jsonObj; + if (result) { // Done return true; @@ -1867,7 +1910,9 @@ bool ChannelWebAPIUtils::getChannelReportValue(unsigned int deviceIndex, unsigne { // Get value of requested key QJsonObject *jsonObj = channelReport.asJsonObject(); - if (WebAPIUtils::getSubObjectString(*jsonObj, key, value)) + bool result = WebAPIUtils::getSubObjectString(*jsonObj, key, value); + delete jsonObj; + if (result) { // Done return true; diff --git a/sdrbase/channel/channelwebapiutils.h b/sdrbase/channel/channelwebapiutils.h index 6e65cfceff..1bfc7e8087 100644 --- a/sdrbase/channel/channelwebapiutils.h +++ b/sdrbase/channel/channelwebapiutils.h @@ -23,7 +23,6 @@ #include #include -#include #include "SWGDeviceSettings.h" #include "SWGDeviceReport.h" @@ -72,7 +71,7 @@ class SDRBASE_API ChannelWebAPIUtils static bool getDeviceSetting(unsigned int deviceIndex, const QString &setting, int &value); static bool getDeviceReportValue(unsigned int deviceIndex, const QString &key, QString &value); static bool getDeviceReportList(unsigned int deviceIndex, const QString &key, const QString &subKey, QList &values); - static bool getDevicePosition(unsigned int deviceIndex, QGeoCoordinate& position); + static bool getDevicePosition(unsigned int deviceIndex, float& latitude, float& longitude, float& altitude); static bool patchDeviceSetting(unsigned int deviceIndex, const QString &setting, int value); static bool runFeature(unsigned int featureSetIndex, unsigned int featureIndex); static bool stopFeature(unsigned int featureSetIndex, unsigned int featureIndex); diff --git a/sdrbase/dsp/devicesamplesource.h b/sdrbase/dsp/devicesamplesource.h index c6fdce06f7..6b93dadcbe 100644 --- a/sdrbase/dsp/devicesamplesource.h +++ b/sdrbase/dsp/devicesamplesource.h @@ -165,6 +165,10 @@ class SDRBASE_API DeviceSampleSource : public QObject { protected slots: void handleInputMessages(); +signals: + void positionChanged(float latitude, float longitude, float altitude); + void directionChanged(bool isotropic, float azimuth, float elevation); + protected: SampleSinkFifo m_sampleFifo; MessageQueue m_inputMessageQueue; //!< Input queue to the source