From 68603fec433b33caaa913955bf8e8ecb00e0d7a1 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 20 Dec 2022 21:06:39 +0000 Subject: [PATCH] Allow sampling devices to be refreshed while SDRangel is running. (Possibly need to add a mutex for MainCore::getPluginManager, so only can be used by one thread) Add option to automatically update My Position based on GPS. This is started in MainCore, so we get position as soon as possible. Don't set QFileDialog::DontUseNativeDialog on Android, as Qt's file dialog can't access user storage. Set globally for Linux/Windows, rather than for each dialog. MainWindow: - Add welcome dialog for Android. - Don't show menu bar or status bar on Android to save screen space. - On Android, change tab position when screen orientation changes. - Load default configurations and presets first time SDRangel is run. - Change loadConfiguration to use a QProgressDialog rather than QMessageBox, as the latter was crashing on Android. - Use DialogPositioner to ensure dialogs are on screen. --- app/main.cpp | 30 +- sdrbase/CMakeLists.txt | 20 +- sdrbase/device/deviceenumerator.cpp | 132 +++--- sdrbase/device/deviceenumerator.h | 4 +- sdrbase/maincore.cpp | 37 ++ sdrbase/maincore.h | 12 +- sdrbase/plugin/plugininterface.h | 12 +- sdrbase/settings/mainsettings.h | 6 + sdrbase/settings/preferences.cpp | 6 +- sdrbase/settings/preferences.h | 7 +- sdrbase/util/android.cpp | 213 +++++++++ sdrbase/util/android.h | 44 ++ sdrgui/gui/configurationsdialog.cpp | 30 +- sdrgui/gui/configurationsdialog.h | 3 +- sdrgui/gui/configurationsdialog.ui | 415 +++++++++--------- sdrgui/gui/devicesetpresetsdialog.cpp | 6 +- sdrgui/gui/myposdialog.ui | 153 ++++--- sdrgui/gui/mypositiondialog.cpp | 23 +- sdrgui/gui/mypositiondialog.h | 4 +- sdrgui/gui/samplingdevicedialog.cpp | 48 +- sdrgui/gui/samplingdevicedialog.h | 3 + sdrgui/gui/samplingdevicedialog.ui | 22 +- sdrgui/mainwindow.cpp | 280 ++++++++++-- sdrgui/mainwindow.h | 9 +- .../configurations/airspyhf/radioclockeu.cfgx | 1 + settings/configurations/rtlsdr/adsb.cfgx | 1 + settings/configurations/rtlsdr/ais.cfgx | 1 + settings/configurations/rtlsdr/apt.cfgx | 1 + settings/configurations/rtlsdr/dab.cfgx | 1 + settings/configurations/rtlsdr/isspacket.cfgx | 1 + .../configurations/rtlsdr/radiosonde.cfgx | 1 + settings/presets/rtlsdr/noaa18.prex | 1 + settings/presets/rtlsdr/noaa19.prex | 1 + settings/settings.qrc | 13 + 34 files changed, 1125 insertions(+), 416 deletions(-) create mode 100644 sdrbase/util/android.cpp create mode 100644 sdrbase/util/android.h create mode 100644 settings/configurations/airspyhf/radioclockeu.cfgx create mode 100644 settings/configurations/rtlsdr/adsb.cfgx create mode 100644 settings/configurations/rtlsdr/ais.cfgx create mode 100644 settings/configurations/rtlsdr/apt.cfgx create mode 100644 settings/configurations/rtlsdr/dab.cfgx create mode 100644 settings/configurations/rtlsdr/isspacket.cfgx create mode 100644 settings/configurations/rtlsdr/radiosonde.cfgx create mode 100644 settings/presets/rtlsdr/noaa18.prex create mode 100644 settings/presets/rtlsdr/noaa19.prex create mode 100644 settings/settings.qrc diff --git a/app/main.cpp b/app/main.cpp index f3f6ce875..25c12f281 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -26,6 +26,9 @@ #include #include #endif +#ifdef ANDROID +#include "util/android.h" +#endif #include "loggerwithfile.h" #include "mainwindow.h" @@ -49,6 +52,9 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) && (QT_VERSION <= QT_VERSION_CHECK(6, 0, 0)) QApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton); #endif +#ifndef ANDROID + QApplication::setAttribute(Qt::AA_DontUseNativeDialogs); // Don't use on Android, otherwise we can't access files on internal storage +#endif QApplication a(argc, argv); @@ -111,6 +117,20 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo #endif #endif + +#ifdef ANDROID + // Default sized sliders can be hard to move using touch GUIs, so increase szie + // FIXME: How can we do a double border around the handle, as Fusion style seems to use? + // Dialog borders are hard to see as is (perhaps as Android doesn't have a title bar), so use same color as for MDI + qApp->setStyleSheet("QSlider {min-height: 20px; } " + "QSlider::groove:horizontal { border: 1px solid #2e2e2e; height: 1px; background: #444444; margin: 1px 0;}" + "QSlider::handle:horizontal { background: #585858; border: 1px double #676767; width: 16px; margin: -8px 0px; border-radius: 3px;}" + "QSlider::sub-page {background: #ff8c00; border: 1px solid #2e2e2e;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-top-left-radius: 5px;border-bottom-left-radius: 5px;}" + "QSlider::add-page {background: #444444; border: 1px solid #2e2e2e;border-top-right-radius: 5px;border-bottom-right-radius: 5px;border-top-left-radius: 0px;border-bottom-left-radius: 0px;}" + "QDialog { border: 1px solid #ff8c00;}" + ); +#endif + MainParser parser; parser.parse(*qApp); @@ -160,10 +180,18 @@ int main(int argc, char* argv[]) QSurfaceFormat::setDefaultFormat(sfc); #endif - qtwebapp::LoggerWithFile *logger = new qtwebapp::LoggerWithFile(qApp); +#ifdef ANDROID + qtwebapp::LoggerWithFile *logger = nullptr; + qInstallMessageHandler(Android::messageHandler); +#else + qtwebapp::LoggerWithFile *logger = new qtwebapp::LoggerWithFile(qApp); logger->installMsgHandler(); +#endif + int res = runQtApplication(argc, argv, logger); + delete logger; + qWarning("SDRangel quit."); return res; } diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index d1bcb297e..13faff1c9 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -1,6 +1,7 @@ project (sdrbase) if(WIN32) + # This should probably be in ../CMakeLists.txt with the other variables like it set(OPUS_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/external/windows/libopus/include") set(OPUS_LIBRARIES "${CMAKE_SOURCE_DIR}/external/windows/libopus/lib/x64/libopus.lib") endif() @@ -45,10 +46,11 @@ if (LIBSIGMF_FOUND AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(sdrbase_LIBSIGMF_LIB ${LIBSIGMF_LIBRARIES}) endif() -# serialdv now required -add_definitions(-DDSD_USE_SERIALDV) -include_directories(${LIBSERIALDV_INCLUDE_DIR}) -set(sdrbase_SERIALDV_LIB ${LIBSERIALDV_LIBRARY}) +if (LIBSERIALDV_FOUND) + add_definitions(-DDSD_USE_SERIALDV) + include_directories(${LIBSERIALDV_INCLUDE_DIR}) + set(sdrbase_SERIALDV_LIB ${LIBSERIALDV_LIBRARY}) +endif() set(sdrbase_SOURCES ${sdrbase_SOURCES} @@ -168,6 +170,7 @@ set(sdrbase_SOURCES settings/rollupstate.cpp util/ais.cpp + util/android.cpp util/aviationweather.cpp util/ax25.cpp util/aprs.cpp @@ -388,6 +391,7 @@ set(sdrbase_HEADERS settings/rollupstate.h util/ais.h + util/android.h util/aviationweather.h util/ax25.h util/aprs.h @@ -491,6 +495,7 @@ target_link_libraries(sdrbase Qt::Core Qt::Multimedia Qt::WebSockets + Qt::Positioning httpserver logging qrtplib @@ -499,8 +504,15 @@ target_link_libraries(sdrbase if (Qt6_FOUND) target_link_libraries(sdrbase Qt::Core5Compat + Qt::CorePrivate ) endif() +if(ANDROID AND NOT ENABLE_QT6) + target_link_libraries(sdrbase Qt::AndroidExtras) +endif() +if(ANDROID) + target_link_libraries(sdrbase log) +endif() install(TARGETS sdrbase DESTINATION ${INSTALL_LIB_DIR}) diff --git a/sdrbase/device/deviceenumerator.cpp b/sdrbase/device/deviceenumerator.cpp index f4ecd56c9..8ca2e8038 100644 --- a/sdrbase/device/deviceenumerator.cpp +++ b/sdrbase/device/deviceenumerator.cpp @@ -17,8 +17,6 @@ #include -#include "plugin/pluginmanager.h" - #include "deviceenumerator.h" Q_GLOBAL_STATIC(DeviceEnumerator, deviceEnumerator) @@ -246,89 +244,101 @@ bool DeviceEnumerator::isMIMOEnumerated(const QString& deviceHwId, int deviceSeq return false; } -void DeviceEnumerator::enumerateRxDevices(PluginManager *pluginManager) +void DeviceEnumerator::enumerateDevices(PluginAPI::SamplingDeviceRegistrations& deviceRegistrations, DevicesEnumeration& enumeration, PluginInterface::SamplingDevice::StreamType type) { - m_rxEnumeration.clear(); - PluginAPI::SamplingDeviceRegistrations& rxDeviceRegistrations = pluginManager->getSourceDeviceRegistrations(); - int index = 0; + DevicesEnumeration tempEnumeration; + PluginInterface::OriginDevices originDevices; + QStringList originDevicesHwIds; - for (int i = 0; i < rxDeviceRegistrations.count(); i++) + for (int i = 0; i < deviceRegistrations.count(); i++) { - qDebug("DeviceEnumerator::enumerateRxDevices: %s", qPrintable(rxDeviceRegistrations[i].m_deviceId)); - rxDeviceRegistrations[i].m_plugin->enumOriginDevices(m_originDevicesHwIds, m_originDevices); - PluginInterface::SamplingDevices samplingDevices = rxDeviceRegistrations[i].m_plugin->enumSampleSources(m_originDevices); + qDebug("DeviceEnumerator::enumerateDevices: %s", qPrintable(deviceRegistrations[i].m_deviceId)); + deviceRegistrations[i].m_plugin->enumOriginDevices(originDevicesHwIds, originDevices); + PluginInterface::SamplingDevices samplingDevices; + if (type == PluginInterface::SamplingDevice::StreamSingleRx) { + samplingDevices = deviceRegistrations[i].m_plugin->enumSampleSources(originDevices); + } else if (type == PluginInterface::SamplingDevice::StreamSingleTx) { + samplingDevices = deviceRegistrations[i].m_plugin->enumSampleSinks(originDevices); + } else { + samplingDevices = deviceRegistrations[i].m_plugin->enumSampleMIMO(originDevices); + } for (int j = 0; j < samplingDevices.count(); j++) { - m_rxEnumeration.push_back( + tempEnumeration.push_back( DeviceEnumeration( samplingDevices[j], - rxDeviceRegistrations[i].m_plugin, - index + deviceRegistrations[i].m_plugin, + 0 // Index will be set when adding to enumeration below ) ); - index++; } } + + // We don't remove devices that are no-longer found from the enumeration list, in case their + // index is referenced in some other object (E.g. DeviceGUI) + // Instead we mark as removed. If later re-added, then we re-use the same index + for (DevicesEnumeration::iterator it = enumeration.begin(); it != enumeration.end(); ++it) + { + bool found = false; + for (DevicesEnumeration::iterator it2 = tempEnumeration.begin(); it2 != tempEnumeration.end(); ++it2) + { + if (it->m_samplingDevice == it2->m_samplingDevice) + { + found = true; + break; + } + } + if (!found) { + it->m_samplingDevice.removed = true; + } + } + + // Add new entries and update existing (in case re-added or sequence number has changed) + int index = enumeration.size(); + for (DevicesEnumeration::iterator it = tempEnumeration.begin(); it != tempEnumeration.end(); ++it) + { + + bool found = false; + for (DevicesEnumeration::iterator it2 = enumeration.begin(); it2 != enumeration.end(); ++it2) + { + if (it->m_samplingDevice == it2->m_samplingDevice) + { + it2->m_samplingDevice.removed = false; + it2->m_samplingDevice.displayedName = it->m_samplingDevice.displayedName; + found = true; + break; + } + + } + if (!found) + { + it->m_index = index++; + enumeration.push_back(*it); + } + } +} + +void DeviceEnumerator::enumerateRxDevices(PluginManager *pluginManager) +{ + enumerateDevices(pluginManager->getSourceDeviceRegistrations(), m_rxEnumeration, PluginInterface::SamplingDevice::StreamSingleRx); } void DeviceEnumerator::enumerateTxDevices(PluginManager *pluginManager) { - m_txEnumeration.clear(); - PluginAPI::SamplingDeviceRegistrations& txDeviceRegistrations = pluginManager->getSinkDeviceRegistrations(); - int index = 0; - - for (int i = 0; i < txDeviceRegistrations.count(); i++) - { - qDebug("DeviceEnumerator::enumerateTxDevices: %s", qPrintable(txDeviceRegistrations[i].m_deviceId)); - txDeviceRegistrations[i].m_plugin->enumOriginDevices(m_originDevicesHwIds, m_originDevices); - PluginInterface::SamplingDevices samplingDevices = txDeviceRegistrations[i].m_plugin->enumSampleSinks(m_originDevices); - - for (int j = 0; j < samplingDevices.count(); j++) - { - m_txEnumeration.push_back( - DeviceEnumeration( - samplingDevices[j], - txDeviceRegistrations[i].m_plugin, - index - ) - ); - index++; - } - } + enumerateDevices(pluginManager->getSinkDeviceRegistrations(), m_txEnumeration, PluginInterface::SamplingDevice::StreamSingleTx); } void DeviceEnumerator::enumerateMIMODevices(PluginManager *pluginManager) { - m_mimoEnumeration.clear(); - PluginAPI::SamplingDeviceRegistrations& mimoDeviceRegistrations = pluginManager->getMIMODeviceRegistrations(); - int index = 0; - - for (int i = 0; i < mimoDeviceRegistrations.count(); i++) - { - qDebug("DeviceEnumerator::enumerateMIMODevices: %s", qPrintable(mimoDeviceRegistrations[i].m_deviceId)); - mimoDeviceRegistrations[i].m_plugin->enumOriginDevices(m_originDevicesHwIds, m_originDevices); - PluginInterface::SamplingDevices samplingDevices = mimoDeviceRegistrations[i].m_plugin->enumSampleMIMO(m_originDevices); - - for (int j = 0; j < samplingDevices.count(); j++) - { - m_mimoEnumeration.push_back( - DeviceEnumeration( - samplingDevices[j], - mimoDeviceRegistrations[i].m_plugin, - index - ) - ); - index++; - } - } + enumerateDevices(pluginManager->getMIMODeviceRegistrations(), m_mimoEnumeration, PluginInterface::SamplingDevice::StreamMIMO); } void DeviceEnumerator::listRxDeviceNames(QList& list, std::vector& indexes) const { for (DevicesEnumeration::const_iterator it = m_rxEnumeration.begin(); it != m_rxEnumeration.end(); ++it) { - if ((it->m_samplingDevice.claimed < 0) || (it->m_samplingDevice.type == PluginInterface::SamplingDevice::BuiltInDevice)) + if (((it->m_samplingDevice.claimed < 0) && (!it->m_samplingDevice.removed)) || (it->m_samplingDevice.type == PluginInterface::SamplingDevice::BuiltInDevice)) { list.append(it->m_samplingDevice.displayedName); indexes.push_back(it->m_index); @@ -340,7 +350,7 @@ void DeviceEnumerator::listTxDeviceNames(QList& list, std::vector& { for (DevicesEnumeration::const_iterator it = m_txEnumeration.begin(); it != m_txEnumeration.end(); ++it) { - if ((it->m_samplingDevice.claimed < 0) || (it->m_samplingDevice.type == PluginInterface::SamplingDevice::BuiltInDevice)) + if (((it->m_samplingDevice.claimed < 0) && (!it->m_samplingDevice.removed)) || (it->m_samplingDevice.type == PluginInterface::SamplingDevice::BuiltInDevice)) { list.append(it->m_samplingDevice.displayedName); indexes.push_back(it->m_index); @@ -352,7 +362,7 @@ void DeviceEnumerator::listMIMODeviceNames(QList& list, std::vectorm_samplingDevice.claimed < 0) || (it->m_samplingDevice.type == PluginInterface::SamplingDevice::BuiltInDevice)) + if (((it->m_samplingDevice.claimed < 0) && (!it->m_samplingDevice.removed)) || (it->m_samplingDevice.type == PluginInterface::SamplingDevice::BuiltInDevice)) { list.append(it->m_samplingDevice.displayedName); indexes.push_back(it->m_index); diff --git a/sdrbase/device/deviceenumerator.h b/sdrbase/device/deviceenumerator.h index 3cd7e68d4..0c35f3f43 100644 --- a/sdrbase/device/deviceenumerator.h +++ b/sdrbase/device/deviceenumerator.h @@ -21,6 +21,7 @@ #include #include "plugin/plugininterface.h" +#include "plugin/pluginmanager.h" #include "device/deviceuserargs.h" #include "export.h" @@ -85,9 +86,8 @@ private: DevicesEnumeration m_rxEnumeration; DevicesEnumeration m_txEnumeration; DevicesEnumeration m_mimoEnumeration; - PluginInterface::OriginDevices m_originDevices; - QStringList m_originDevicesHwIds; + void enumerateDevices(PluginAPI::SamplingDeviceRegistrations& deviceRegistrations, DevicesEnumeration& enumeration, PluginInterface::SamplingDevice::StreamType type); PluginInterface *getRxRegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId); PluginInterface *getTxRegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId); PluginInterface *getMIMORegisteredPlugin(PluginManager *pluginManager, const QString& deviceHwId); diff --git a/sdrbase/maincore.cpp b/sdrbase/maincore.cpp index ee84eda5f..44dc1866f 100644 --- a/sdrbase/maincore.cpp +++ b/sdrbase/maincore.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include "loggerwithfile.h" #include "dsp/dsptypes.h" @@ -71,6 +73,8 @@ MainCore::MainCore() m_masterTimer.start(50); m_startMsecsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); m_masterElapsedTimer.start(); + // Position can take a while to determine, so we start updates at program startup + initPosition(); } MainCore::~MainCore() @@ -335,3 +339,36 @@ void MainCore::debugMaps() feIt.value()->getIndex(), feIt.key()->getIndexInFeatureSet(), qPrintable(feIt.key()->getURI()), qPrintable(feIt.key()->getName())); } } + +void MainCore::initPosition() +{ + m_positionSource = QGeoPositionInfoSource::createDefaultSource(this); + if (m_positionSource) + { + connect(m_positionSource, &QGeoPositionInfoSource::positionUpdated, this, &MainCore::positionUpdated); + m_positionSource->startUpdates(); + } + else + { + qDebug() << "MainCore::initPosition: No position source."; + } +} + +const QGeoPositionInfo& MainCore::getPosition() const +{ + return m_position; +} + +void MainCore::positionUpdated(const QGeoPositionInfo &info) +{ + if (info.isValid()) + { + m_position = info; + if (m_settings.getAutoUpdatePosition()) + { + m_settings.setLatitude(m_position.coordinate().latitude()); + m_settings.setLongitude(m_position.coordinate().longitude()); + m_settings.setAltitude(m_position.coordinate().altitude()); + } + } +} diff --git a/sdrbase/maincore.h b/sdrbase/maincore.h index dcf44ddef..e2c86ebd9 100644 --- a/sdrbase/maincore.h +++ b/sdrbase/maincore.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "export.h" #include "settings/mainsettings.h" @@ -38,6 +39,7 @@ class FeatureSet; class Feature; class PluginManager; class MessageQueue; +class QGeoPositionInfoSource; namespace qtwebapp { class LoggerWithFile; @@ -846,7 +848,7 @@ public: qint64 getStartMsecsSinceEpoch() const { return m_startMsecsSinceEpoch; } //!< Epoch timestamp in millisecodns close to elapsed timer start const MainSettings& getSettings() const { return m_settings; } MessageQueue *getMainMessageQueue() { return m_mainMessageQueue; } - const PluginManager *getPluginManager() const { return m_pluginManager; } + PluginManager *getPluginManager() const { return m_pluginManager; } std::vector& getDeviceSets() { return m_deviceSets; } std::vector& getFeatureeSets() { return m_featureSets; } void setLoggingOptions(); @@ -875,6 +877,8 @@ public: // pipes MessagePipes& getMessagePipes() { return m_messagePipes; } DataPipes& getDataPipes() { return m_dataPipes; } + // Position + const QGeoPositionInfo& getPosition() const; friend class MainServer; friend class MainWindow; @@ -883,6 +887,9 @@ public: friend class DeviceSetPresetsDialog; friend class ConfigurationsDialog; +public slots: + void positionUpdated(const QGeoPositionInfo &info); + signals: void deviceSetAdded(int index, DeviceAPI *device); void deviceChanged(int index); @@ -912,7 +919,10 @@ private: PluginManager* m_pluginManager; MessagePipes m_messagePipes; DataPipes m_dataPipes; + QGeoPositionInfoSource *m_positionSource; + QGeoPositionInfo m_position; + void initPosition(); void debugMaps(); }; diff --git a/sdrbase/plugin/plugininterface.h b/sdrbase/plugin/plugininterface.h index 8dff4d372..b60ad4676 100644 --- a/sdrbase/plugin/plugininterface.h +++ b/sdrbase/plugin/plugininterface.h @@ -66,6 +66,7 @@ public: int deviceNbItems; //!< Number of items (or streams) in the device. >1 for composite devices. int deviceItemIndex; //!< For composite devices this is the Rx or Tx stream index. -1 if not initialized int claimed; //!< This is the device set index if claimed else -1 + bool removed; //!< Set if device has been removed SamplingDevice(const QString& _displayedName, const QString& _hardwareId, @@ -85,8 +86,17 @@ public: streamType(_streamType), deviceNbItems(_deviceNbItems), deviceItemIndex(_deviceItemIndex), - claimed(-1) + claimed(-1), + removed(false) { } + + bool operator==(const SamplingDevice& rhs) const + { + return displayedName == rhs.displayedName + && hardwareId == rhs.hardwareId + && id == rhs.id + && serial == rhs.serial; + } }; typedef QList SamplingDevices; diff --git a/sdrbase/settings/mainsettings.h b/sdrbase/settings/mainsettings.h index 26af1c809..27573666f 100644 --- a/sdrbase/settings/mainsettings.h +++ b/sdrbase/settings/mainsettings.h @@ -151,6 +151,12 @@ public: emit preferenceChanged(Preferences::Altitude); } + bool getAutoUpdatePosition() const { return m_preferences.getAutoUpdatePosition(); } + void setAutoUpdatePosition(bool autoUpdatePosition) + { + m_preferences.setAutoUpdatePosition(autoUpdatePosition); + } + QtMsgType getConsoleMinLogLevel() const { return m_preferences.getConsoleMinLogLevel(); } void setConsoleMinLogLevel(const QtMsgType& minLogLevel) { diff --git a/sdrbase/settings/preferences.cpp b/sdrbase/settings/preferences.cpp index 156074c93..dbef62e1e 100644 --- a/sdrbase/settings/preferences.cpp +++ b/sdrbase/settings/preferences.cpp @@ -17,6 +17,7 @@ void Preferences::resetToDefaults() m_latitude = 49.012423; // Set an interesting location so map doesn't open up in the middle of the ocean m_longitude = 8.418125; m_altitude = 0.0f; + m_autoUpdatePosition = true; m_useLogFile = false; m_logFileName = "sdrangel.log"; m_consoleMinLogLevel = QtDebugMsg; @@ -41,6 +42,7 @@ QByteArray Preferences::serialize() const s.writeFloat((int) Altitude, m_altitude); s.writeS32((int) SourceItemIndex, m_sourceItemIndex); s.writeS32((int) Multisampling, m_multisampling); + s.writeBool((int) AutoUpdatePosition, m_autoUpdatePosition); return s.final(); } @@ -95,9 +97,11 @@ bool Preferences::deserialize(const QByteArray& data) } d.readS32((int) Multisampling, &m_multisampling, 0); + d.readBool((int) AutoUpdatePosition, &m_autoUpdatePosition, true); return true; - } else + } + else { resetToDefaults(); return false; diff --git a/sdrbase/settings/preferences.h b/sdrbase/settings/preferences.h index 07356f78f..87c1d15a0 100644 --- a/sdrbase/settings/preferences.h +++ b/sdrbase/settings/preferences.h @@ -22,7 +22,8 @@ public: StationName, Altitude, SourceItemIndex, - Multisampling + Multisampling, + AutoUpdatePosition }; Preferences(); @@ -60,6 +61,9 @@ public: float getAltitude() const { return m_altitude; } void setAltitude(float altitude) { m_altitude = altitude; } + bool getAutoUpdatePosition() const { return m_autoUpdatePosition; } + void setAutoUpdatePosition(bool autoUpdatePosition) { m_autoUpdatePosition = autoUpdatePosition; } + QtMsgType getConsoleMinLogLevel() const { return m_consoleMinLogLevel; } void setConsoleMinLogLevel(const QtMsgType& minLogLevel) { m_consoleMinLogLevel = minLogLevel; } @@ -87,6 +91,7 @@ protected: float m_latitude; //!< Position of the station float m_longitude; float m_altitude; //!< Altitude in metres + bool m_autoUpdatePosition; //!< Automatically update position from GPS QtMsgType m_consoleMinLogLevel; QtMsgType m_fileMinLogLevel; diff --git a/sdrbase/util/android.cpp b/sdrbase/util/android.cpp new file mode 100644 index 000000000..2d755ae72 --- /dev/null +++ b/sdrbase/util/android.cpp @@ -0,0 +1,213 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifdef ANDROID + +#include + +#include + +#include "android.h" + +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + +#include +#include +#include + +void Android::sendIntent() +{ + QJniObject url = QJniObject::fromString("iqsrc://-f 1090000000 -p 1234 -s 2000000 -a 127.0.0.1 -g 100"); + QJniObject intent = QJniObject::callStaticObjectMethod("android/content/Intent", "parseUri", "(Ljava/lang/String;I)Landroid/content/Intent;", url.object(), 0x00000001); // Creates Intent(ACTION_VIEW, url) + QtAndroidPrivate::startActivity(intent, 0, [](int requestCode, int resultCode, const QJniObject &data) { + (void) data; + + qDebug() << "MainCore::sendIntent " << requestCode << resultCode; + }); +} + +QStringList Android::listUSBDeviceSerials(int vid, int pid) +{ + QStringList serials; + QJniEnvironment jniEnv; + + QJniObject activity = QJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) + { + QJniObject serialsObj = activity.callObjectMethod("listUSBDeviceSerials", "(II)[Ljava/lang/String;", vid, pid); + int serialsLen = jniEnv->GetArrayLength(serialsObj.object()); + for (int i = 0; i < serialsLen; i++) + { + QJniObject arrayElement = jniEnv->GetObjectArrayElement(serialsObj.object(), i); + QString serial = arrayElement.toString(); + serials.append(serial); + } + } + + return serials; +} + +int Android::openUSBDevice(const QString &serial) +{ + int fd = -1; + QJniObject activity = QJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) + { + QJniObject serialsObj = QJniObject::fromString(serial); + fd = activity.callMethod("openUSBDevice", "(Ljava/lang/String;)I", serialsObj.object()); + } + + return fd; +} + +void Android::closeUSBDevice(int fd) +{ + if (fd >= 0) + { + QJniObject activity = QJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) { + activity.callMethod("closeUSBDevice", "(I)V", fd); + } else { + qCritical() << "MainCore::closeUSBDevice: activity is not valid."; + } + } +} + +void Android::moveTaskToBack() +{ + QJniObject activity = QJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) { + activity.callMethod("moveTaskToBack", "(Z)Z", true); + } +} + +#else // QT_VERSION + +#include +#include +#include +#include +#include + +void Android::sendIntent() +{ + QAndroidJniObject url = QAndroidJniObject::fromString("iqsrc://-f 1090000000 -p 1234 -s 2000000 -a 127.0.0.1 -g 100"); + QAndroidJniObject intent = QAndroidJniObject::callStaticObjectMethod("android/content/Intent", "parseUri", "(Ljava/lang/String;I)Landroid/content/Intent;", url.object(), 0x00000001); // Creates Intent(ACTION_VIEW, url) + QtAndroid::startActivity(intent, 0, [](int requestCode, int resultCode, const QAndroidJniObject &data) { + (void) data; + + qDebug() << "MainCore::sendIntent " << requestCode << resultCode; + }); +} + +QStringList Android::listUSBDeviceSerials(int vid, int pid) +{ + QStringList serials; + QAndroidJniEnvironment jniEnv; + + QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) + { + QAndroidJniObject serialsObj = activity.callObjectMethod("listUSBDeviceSerials", "(II)[Ljava/lang/String;", vid, pid); + int serialsLen = jniEnv->GetArrayLength(serialsObj.object()); + for (int i = 0; i < serialsLen; i++) + { + QAndroidJniObject arrayElement = jniEnv->GetObjectArrayElement(serialsObj.object(), i); + QString serial = arrayElement.toString(); + serials.append(serial); + } + } + + return serials; +} + +int Android::openUSBDevice(const QString &serial) +{ + int fd = -1; + QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) + { + QAndroidJniObject serialsObj = QAndroidJniObject::fromString(serial); + fd = activity.callMethod("openUSBDevice", "(Ljava/lang/String;)I", serialsObj.object()); + } + + return fd; +} + +void Android::closeUSBDevice(int fd) +{ + if (fd >= 0) + { + QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) { + activity.callMethod("closeUSBDevice", "(I)V", fd); + } else { + qCritical() << "MainCore::closeUSBDevice: activity is not valid."; + } + } +} + +void Android::moveTaskToBack() +{ + QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); + if (activity.isValid()) { + activity.callMethod("moveTaskToBack", "(Z)Z", true); + } +} + +#endif // QT6 + +// Redirect qDebug/qWarning to Android log, so we can view remotely with adb +void Android::messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) +{ + QString report = msg; + if (context.file && !QString(context.file).isEmpty()) + { + report += " in file "; + report += QString(context.file); + report += " line "; + report += QString::number(context.line); + } + if (context.function && !QString(context.function).isEmpty()) + { + report += +" function "; + report += QString(context.function); + } + const char * const local = report.toLocal8Bit().constData(); + const char * const applicationName = "sdrangel"; + switch (type) + { + case QtDebugMsg: + __android_log_write(ANDROID_LOG_DEBUG, applicationName, local); + break; + case QtInfoMsg: + __android_log_write(ANDROID_LOG_INFO, applicationName, local); + break; + case QtWarningMsg: + __android_log_write(ANDROID_LOG_WARN, applicationName, local); + break; + case QtCriticalMsg: + __android_log_write(ANDROID_LOG_ERROR, applicationName, local); + break; + case QtFatalMsg: + default: + __android_log_write(ANDROID_LOG_FATAL, applicationName, local); + abort(); + } +} + +#endif // ANDROID diff --git a/sdrbase/util/android.h b/sdrbase/util/android.h new file mode 100644 index 000000000..ef97d5eed --- /dev/null +++ b/sdrbase/util/android.h @@ -0,0 +1,44 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRBASE_ANDROID_H_ +#define SDRBASE_ANDROID_H_ + +#ifdef ANDROID + +#include +#include + +#include "export.h" + +// Android specific functions +class SDRBASE_API Android +{ +public: + + static void sendIntent(); + static QStringList listUSBDeviceSerials(int vid, int pid); + static int openUSBDevice(const QString &serial); + static void closeUSBDevice(int fd); + static void moveTaskToBack(); + static void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg); + +}; + +#endif // ANDROID + +#endif // SDRBASE_ANDROID_H_ diff --git a/sdrgui/gui/configurationsdialog.cpp b/sdrgui/gui/configurationsdialog.cpp index c324f18b2..f05756277 100644 --- a/sdrgui/gui/configurationsdialog.cpp +++ b/sdrgui/gui/configurationsdialog.cpp @@ -27,11 +27,26 @@ #include "settings/configuration.h" -ConfigurationsDialog::ConfigurationsDialog(QWidget* parent) : +ConfigurationsDialog::ConfigurationsDialog(bool openOnly, QWidget* parent) : QDialog(parent), ui(new Ui::ConfigurationsDialog) { ui->setupUi(this); + if (openOnly) + { + ui->buttonBox->setStandardButtons(QDialogButtonBox::Close | QDialogButtonBox::Open); + ui->configurationDelete->setVisible(false); + ui->configurationEdit->setVisible(false); + ui->configurationExport->setVisible(false); + ui->configurationImport->setVisible(false); + ui->configurationLoad->setVisible(false); + ui->configurationSave->setVisible(false); + ui->configurationUpdate->setVisible(false); + } + else + { + ui->description->setVisible(false); + } } ConfigurationsDialog::~ConfigurationsDialog() @@ -354,9 +369,7 @@ void ConfigurationsDialog::on_configurationExport_clicked() tr("Open preset export file"), ".", tr("Configuration export files (*.cfgx)"), - 0, - QFileDialog::DontUseNativeDialog - ); + 0); if (fileName != "") { @@ -404,8 +417,7 @@ void ConfigurationsDialog::on_configurationImport_clicked() tr("Open preset export file"), ".", tr("Preset export files (*.cfgx)"), - 0, - QFileDialog::DontUseNativeDialog + 0 ); if (fileName != "") @@ -497,3 +509,9 @@ void ConfigurationsDialog::deleteConfigurationGroup(const QString& groupName) } } } + +void ConfigurationsDialog::accept() +{ + on_configurationLoad_clicked(); + QDialog::accept(); +} diff --git a/sdrgui/gui/configurationsdialog.h b/sdrgui/gui/configurationsdialog.h index 6ca575d77..1d728fb52 100644 --- a/sdrgui/gui/configurationsdialog.h +++ b/sdrgui/gui/configurationsdialog.h @@ -38,7 +38,7 @@ namespace Ui { class SDRGUI_API ConfigurationsDialog : public QDialog { Q_OBJECT public: - explicit ConfigurationsDialog(QWidget* parent = nullptr); + explicit ConfigurationsDialog(bool openOnly, QWidget* parent = nullptr); ~ConfigurationsDialog(); void setConfigurations(QList* configurations) { m_configurations = configurations; } void populateTree(); @@ -71,6 +71,7 @@ private slots: void on_configurationLoad_clicked(); void on_configurationTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); void on_configurationTree_itemActivated(QTreeWidgetItem *item, int column); + void accept() override; signals: void saveConfiguration(Configuration*); diff --git a/sdrgui/gui/configurationsdialog.ui b/sdrgui/gui/configurationsdialog.ui index 23430dbf5..21cf06e35 100644 --- a/sdrgui/gui/configurationsdialog.ui +++ b/sdrgui/gui/configurationsdialog.ui @@ -6,8 +6,8 @@ 0 0 - 392 - 414 + 410 + 424 @@ -19,218 +19,207 @@ Configurations - - - - 40 - 380 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Close - - - - - - 0 - 10 - 392 - 310 - - - - - - - List of configurations - - - 5 - - - true - - - 1 - - - 5 - - - - Description + + + + + + + + Select configuration to load: + + + + + + + List of configurations + + + 5 + + + true + + + 1 + + + 5 + + + + Description + + + + + + + + + + + + + Save current workspaces configuration as new configuration - - - - - - - - - 0 - 330 - 392 - 34 - - - - - - - Save current workspaces configuration as new configuration - - - ... - - - - :/create.png:/create.png - - - - 16 - 16 - - - - - - - - Update selected configuration with current workspaces configuration - - - ... - - - - :/recycle.png:/recycle.png - - - - 16 - 16 - - - - - - - - Edit configuration details - - - - - - - :/edit.png:/edit.png - - - - - - - Export current configuration to file - - - - - - - :/export.png:/export.png - - - - - - - Import configuration from file into current group - - - - - - - :/import.png:/import.png - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Delete selected configuration - - - ... - - - - :/bin.png:/bin.png - - - - 16 - 16 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Load selected configuration - - - ... - - - - :/load.png:/load.png - - - - 16 - 16 - - - - - - + + ... + + + + :/create.png:/create.png + + + + 16 + 16 + + + + + + + + Update selected configuration with current workspaces configuration + + + ... + + + + :/recycle.png:/recycle.png + + + + 16 + 16 + + + + + + + + Edit configuration details + + + + + + + :/edit.png:/edit.png + + + + + + + Export current configuration to file + + + + + + + :/export.png:/export.png + + + + + + + Import configuration from file into current group + + + + + + + :/import.png:/import.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Delete selected configuration + + + ... + + + + :/bin.png:/bin.png + + + + 16 + 16 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Load selected configuration + + + ... + + + + :/load.png:/load.png + + + + 16 + 16 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + diff --git a/sdrgui/gui/devicesetpresetsdialog.cpp b/sdrgui/gui/devicesetpresetsdialog.cpp index 7e066519a..0422bbac0 100644 --- a/sdrgui/gui/devicesetpresetsdialog.cpp +++ b/sdrgui/gui/devicesetpresetsdialog.cpp @@ -292,8 +292,7 @@ void DeviceSetPresetsDialog::on_presetExport_clicked() tr("Open preset export file"), ".", tr("Preset export files (*.prex)"), - 0, - QFileDialog::DontUseNativeDialog + 0 ); if (fileName != "") @@ -342,8 +341,7 @@ void DeviceSetPresetsDialog::on_presetImport_clicked() tr("Open preset export file"), ".", tr("Preset export files (*.prex)"), - 0, - QFileDialog::DontUseNativeDialog + 0 ); if (fileName != "") diff --git a/sdrgui/gui/myposdialog.ui b/sdrgui/gui/myposdialog.ui index fde93a7b0..977ed6bda 100644 --- a/sdrgui/gui/myposdialog.ui +++ b/sdrgui/gui/myposdialog.ui @@ -7,7 +7,7 @@ 0 0 324 - 229 + 201 @@ -19,44 +19,24 @@ My Position - - + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + My Station Position - - - - - Latitude - - - - - - - Longitude - - - - - - - Longitude in decimal degrees - - - 6 - - - -180.000000000000000 - - - 180.000000000000000 - - - - + + Latitude in decimal degrees @@ -72,24 +52,14 @@ - - - - Altitude in metres - - - 50000 - - - - - + + - Altitude (m) + Latitude - + Enter the name of your station @@ -99,6 +69,20 @@ + + + + Altitude (m) + + + + + + + Longitude + + + @@ -106,19 +90,66 @@ + + + + Automatically update position using GPS (when available) + + + + + + + + + + Longitude in decimal degrees + + + 6 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + Auto-update from GPS + + + + + + + Set position using GPS (if available) + + + + + + + :/gps.png:/gps.png + + + + + + + Altitude in metres + + + 50000 + + + - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - @@ -127,7 +158,9 @@ longitudeSpinBox altitudeSpinBox - + + + buttonBox diff --git a/sdrgui/gui/mypositiondialog.cpp b/sdrgui/gui/mypositiondialog.cpp index 58c8284a8..5f36bfafc 100644 --- a/sdrgui/gui/mypositiondialog.cpp +++ b/sdrgui/gui/mypositiondialog.cpp @@ -2,9 +2,6 @@ // Copyright (C) 2016 F4EXB // // written by Edouard Griffiths // // // -// OpenGL interface modernization. // -// See: http://doc.qt.io/qt-5/qopenglshaderprogram.html // -// // // 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 // @@ -21,7 +18,9 @@ #include "gui/mypositiondialog.h" #include "ui_myposdialog.h" +#include "maincore.h" +#include MyPositionDialog::MyPositionDialog(MainSettings& mainSettings, QWidget* parent) : QDialog(parent), @@ -33,6 +32,7 @@ MyPositionDialog::MyPositionDialog(MainSettings& mainSettings, QWidget* parent) ui->latitudeSpinBox->setValue(m_mainSettings.getLatitude()); ui->longitudeSpinBox->setValue(m_mainSettings.getLongitude()); ui->altitudeSpinBox->setValue(m_mainSettings.getAltitude()); + ui->autoUpdatePosition->setChecked(m_mainSettings.getAutoUpdatePosition()); } MyPositionDialog::~MyPositionDialog() @@ -46,5 +46,22 @@ void MyPositionDialog::accept() m_mainSettings.setLatitude(ui->latitudeSpinBox->value()); m_mainSettings.setLongitude(ui->longitudeSpinBox->value()); m_mainSettings.setAltitude(ui->altitudeSpinBox->value()); + m_mainSettings.setAutoUpdatePosition(ui->autoUpdatePosition->isChecked()); QDialog::accept(); } + +void MyPositionDialog::on_gps_clicked() +{ + const QGeoPositionInfo& position = MainCore::instance()->getPosition(); + if (position.isValid()) + { + QGeoCoordinate coord = position.coordinate(); + ui->latitudeSpinBox->setValue(coord.latitude()); + ui->longitudeSpinBox->setValue(coord.longitude()); + ui->altitudeSpinBox->setValue(coord.altitude()); + } + else + { + qDebug() << "MyPositionDialog::on_gps_clicked: Position is not valid."; + } +} diff --git a/sdrgui/gui/mypositiondialog.h b/sdrgui/gui/mypositiondialog.h index 2f37642fa..89ce6bd43 100644 --- a/sdrgui/gui/mypositiondialog.h +++ b/sdrgui/gui/mypositiondialog.h @@ -2,9 +2,6 @@ // Copyright (C) 2016 F4EXB // // written by Edouard Griffiths // // // -// OpenGL interface modernization. // -// See: http://doc.qt.io/qt-5/qopenglshaderprogram.html // -// // // 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 // @@ -43,6 +40,7 @@ private: private slots: void accept(); + void on_gps_clicked(); }; #endif /* SDRBASE_GUI_MYPOSITIONDIALOG_H_ */ diff --git a/sdrgui/gui/samplingdevicedialog.cpp b/sdrgui/gui/samplingdevicedialog.cpp index fbbbbfec1..f9251b951 100644 --- a/sdrgui/gui/samplingdevicedialog.cpp +++ b/sdrgui/gui/samplingdevicedialog.cpp @@ -22,7 +22,7 @@ #include "samplingdevicedialog.h" #include "ui_samplingdevicedialog.h" #include "device/deviceenumerator.h" - +#include "maincore.h" SamplingDeviceDialog::SamplingDeviceDialog(int deviceType, QWidget* parent) : QDialog(parent), @@ -32,19 +32,7 @@ SamplingDeviceDialog::SamplingDeviceDialog(int deviceType, QWidget* parent) : m_hasChanged(false) { ui->setupUi(this); - - QList deviceDisplayNames; - - if (m_deviceType == 0) { // Single Rx - DeviceEnumerator::instance()->listRxDeviceNames(deviceDisplayNames, m_deviceIndexes); - } else if (m_deviceType == 1) { // Single Tx - DeviceEnumerator::instance()->listTxDeviceNames(deviceDisplayNames, m_deviceIndexes); - } else if (m_deviceType == 2) { // MIMO - DeviceEnumerator::instance()->listMIMODeviceNames(deviceDisplayNames, m_deviceIndexes); - } - - QStringList devicesNamesList(deviceDisplayNames); - ui->deviceSelect->addItems(devicesNamesList); + on_refreshDevices_clicked(); } SamplingDeviceDialog::~SamplingDeviceDialog() @@ -58,6 +46,23 @@ int SamplingDeviceDialog::exec() return QDialog::exec(); } +void SamplingDeviceDialog::displayDevices() +{ + QList deviceDisplayNames; + + m_deviceIndexes.clear(); + if (m_deviceType == 0) { // Single Rx + DeviceEnumerator::instance()->listRxDeviceNames(deviceDisplayNames, m_deviceIndexes); + } else if (m_deviceType == 1) { // Single Tx + DeviceEnumerator::instance()->listTxDeviceNames(deviceDisplayNames, m_deviceIndexes); + } else if (m_deviceType == 2) { // MIMO + DeviceEnumerator::instance()->listMIMODeviceNames(deviceDisplayNames, m_deviceIndexes); + } + + ui->deviceSelect->clear(); + ui->deviceSelect->addItems(deviceDisplayNames); +} + void SamplingDeviceDialog::setSelectedDeviceIndex(int deviceIndex) { ui->deviceSelect->blockSignals(true); @@ -77,6 +82,21 @@ void SamplingDeviceDialog::on_deviceSelect_currentIndexChanged(int index) m_hasChanged = true; } +void SamplingDeviceDialog::on_refreshDevices_clicked() +{ + PluginManager *pluginManager = MainCore::instance()->getPluginManager(); + + if (m_deviceType == 0) { + DeviceEnumerator::instance()->enumerateRxDevices(pluginManager); + } else if (m_deviceType == 1) { + DeviceEnumerator::instance()->enumerateTxDevices(pluginManager); + } else if (m_deviceType == 2) { + DeviceEnumerator::instance()->enumerateMIMODevices(pluginManager); + } + + displayDevices(); +} + void SamplingDeviceDialog::accept() { m_selectedDeviceIndex = m_deviceIndexes[ui->deviceSelect->currentIndex()]; diff --git a/sdrgui/gui/samplingdevicedialog.h b/sdrgui/gui/samplingdevicedialog.h index 7662e1cec..573212eb6 100644 --- a/sdrgui/gui/samplingdevicedialog.h +++ b/sdrgui/gui/samplingdevicedialog.h @@ -50,8 +50,11 @@ private: std::vector m_deviceIndexes; bool m_hasChanged; + void displayDevices(); + private slots: void on_deviceSelect_currentIndexChanged(int index); + void on_refreshDevices_clicked(); void accept(); void reject(); }; diff --git a/sdrgui/gui/samplingdevicedialog.ui b/sdrgui/gui/samplingdevicedialog.ui index 0b930a6bc..183a3b9a0 100644 --- a/sdrgui/gui/samplingdevicedialog.ui +++ b/sdrgui/gui/samplingdevicedialog.ui @@ -31,8 +31,8 @@ Select from list - - + + @@ -42,6 +42,20 @@ + + + + Refresh list of devices + + + + + + + :/recycle.png:/recycle.png + + + @@ -66,7 +80,9 @@ buttonBox - + + + buttonBox diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index 519f7fe9a..671e6db31 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -18,7 +18,9 @@ #include #include +#include #include +#include #include #include #include @@ -31,10 +33,11 @@ #include #include #include - +#include #include #include #include +#include #include "device/devicegui.h" #include "device/deviceapi.h" @@ -68,6 +71,8 @@ #include "gui/devicesetpresetsdialog.h" #include "gui/commandsdialog.h" #include "gui/configurationsdialog.h" +#include "gui/dialogpositioner.h" +#include "gui/welcomedialog.h" #include "dsp/dspengine.h" #include "dsp/spectrumvis.h" #include "dsp/dspcommands.h" @@ -85,6 +90,9 @@ #include "webapi/webapiserver.h" #include "webapi/webapiadapter.h" #include "commands/command.h" +#ifdef ANDROID +#include "util/android.h" +#endif #include "mainwindow.h" @@ -107,9 +115,13 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse m_mainCore(MainCore::instance()), m_dspEngine(DSPEngine::instance()), m_lastEngineState(DeviceAPI::StNotStarted), + m_dateTimeWidget(nullptr), + m_showSystemWidget(nullptr), m_commandKeyReceiver(nullptr), m_fftWisdomProcess(nullptr) { + bool showWelcome = ANDROID; + qDebug() << "MainWindow::MainWindow: start"; setWindowTitle("SDRangel"); @@ -134,10 +146,21 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse splash->showStatusMessage("starting...", Qt::white); setWindowIcon(QIcon(":/sdrangel_icon.png")); - createMenuBar(); - createStatusBar(); +#ifndef ANDROID + // To save screen space on Android, don't have menu bar. Instead menus are accessed via toolbar button + createMenuBar(nullptr); + createStatusBar(); +#endif +#ifdef ANDROID + if (screen()->isLandscape(screen()->primaryOrientation())) { + setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::West); + } else { + setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::South); + } +#else setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::West); +#endif setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); @@ -146,6 +169,12 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection); + connect(screen(), &QScreen::orientationChanged, this, &MainWindow::orientationChanged); + screen()->setOrientationUpdateMask(Qt::PortraitOrientation + | Qt::LandscapeOrientation + | Qt::InvertedPortraitOrientation + | Qt::InvertedLandscapeOrientation); + connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); m_statusTimer.start(1000); @@ -209,6 +238,16 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse { qDebug() << "MainWindow::MainWindow: no or empty current configuration, creating empty workspace..."; addWorkspace(); + + // If no configurations, load some basic examples + if (m_mainCore->m_settings.getConfigurations().size() == 0) { + loadDefaultConfigurations(); + } + } + else + { + // Only show welcome dialog first time program is run + showWelcome = false; } } @@ -240,6 +279,16 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse restoreGeometry(qUncompress(QByteArray::fromBase64(s.value("mainWindowGeometry").toByteArray()))); restoreState(qUncompress(QByteArray::fromBase64(s.value("mainWindowState").toByteArray()))); + if (showWelcome) + { + // Show welcome dialog + WelcomeDialog welcomeDialog(this); + new DialogPositioner(&welcomeDialog, true); + welcomeDialog.exec(); + // Show configurations + openConfigurationDialog(true); + } + qDebug() << "MainWindow::MainWindow: end"; } @@ -340,6 +389,11 @@ void MainWindow::sampleSourceAdd(Workspace *deviceWorkspace, Workspace *spectrum deviceWorkspace->addToMdiArea(m_deviceUIs.back()->m_deviceGUI); spectrumWorkspace->addToMdiArea(m_deviceUIs.back()->m_mainSpectrumGUI); emit m_mainCore->deviceSetAdded(deviceSetIndex, deviceAPI); + +#ifdef ANDROID + // Seemingly needed on some versions of Android, otherwise the new windows aren't always displayed?? + deviceWorkspace->repaint(); +#endif } void MainWindow::sampleSourceCreate( @@ -1165,7 +1219,9 @@ void MainWindow::loadSettings() m_mainCore->m_settings.load(); m_mainCore->m_settings.sortPresets(); m_mainCore->m_settings.sortCommands(); - m_mainCore->setLoggingOptions(); + if (m_mainCore->m_logger) { + m_mainCore->setLoggingOptions(); + } } void MainWindow::loadDeviceSetPresetSettings(const Preset* preset, int deviceSetIndex) @@ -1230,6 +1286,59 @@ void MainWindow::saveFeatureSetPresetSettings(FeatureSetPreset* preset, int feat featureUI->saveFeatureSetSettings(preset); } +void MainWindow::loadDefaultConfigurations() +{ + QDirIterator configurationsIt(":configurations", QDirIterator::Subdirectories); + while (configurationsIt.hasNext()) + { + QString group = configurationsIt.next(); + QDirIterator groupIt(group, {"*.cfgx"}, QDir::Files); + while (groupIt.hasNext()) + { + QFile file(groupIt.next()); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QByteArray base64Str; + QTextStream instream(&file); + instream >> base64Str; + file.close(); + + Configuration* configuration = MainCore::instance()->m_settings.newConfiguration("", ""); + configuration->deserialize(QByteArray::fromBase64(base64Str)); + } + else + { + qDebug() << "MainWindow::loadDefaultConfigurations: Failed to open configuration " << file.fileName(); + } + } + } + + QDirIterator presetIt(":presets", QDirIterator::Subdirectories); + while (presetIt.hasNext()) + { + QString group = presetIt.next(); + QDirIterator groupIt(group, {"*.prex"}, QDir::Files); + while (groupIt.hasNext()) + { + QFile file(groupIt.next()); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QByteArray base64Str; + QTextStream instream(&file); + instream >> base64Str; + file.close(); + + Preset* preset = MainCore::instance()->m_settings.newPreset("", ""); + preset->deserialize(QByteArray::fromBase64(base64Str)); + } + else + { + qDebug() << "MainWindow::loadDefaultConfigurations: Failed to open preset " << file.fileName(); + } + } + } +} + void MainWindow::loadConfiguration(const Configuration *configuration, bool fromDialog) { qDebug("MainWindow::loadConfiguration: configuration [%s | %s] %d workspace(s) - %d device set(s) - %d feature(s)", @@ -1240,23 +1349,24 @@ void MainWindow::loadConfiguration(const Configuration *configuration, bool from configuration->getFeatureSetPreset().getFeatureCount() ); - QMessageBox *waitBox = nullptr; + QProgressDialog *waitBox = nullptr; if (fromDialog) { - waitBox = new QMessageBox(this); - waitBox->setStandardButtons(QMessageBox::NoButton); - waitBox->setWindowModality(Qt::NonModal); - waitBox->setIcon(QMessageBox::Information); - waitBox->setText("Loading configuration "); - waitBox->setInformativeText("Deleting existing..."); - waitBox->setWindowTitle("Please wait"); - waitBox->show(); - waitBox->raise(); + waitBox = new QProgressDialog("Loading configuration...", "", 0, 100, this); + waitBox->setWindowModality(Qt::WindowModal); + waitBox->setAttribute(Qt::WA_DeleteOnClose, true); + waitBox->setMinimumDuration(0); + waitBox->setCancelButton(nullptr); + waitBox->setValue(1); } // Wipe out everything first - + if (waitBox) + { + waitBox->setLabelText("Deleting existing..."); + waitBox->setValue(5); + } // Device sets while (m_deviceUIs.size() > 0) { removeLastDeviceSet(); @@ -1276,6 +1386,7 @@ void MainWindow::loadConfiguration(const Configuration *configuration, bool from { addWorkspace(); m_workspaces[i]->setAutoStackOption(configuration->getWorkspaceAutoStackOptions()[i]); + m_workspaces[i]->setTabSubWindowsOption(configuration->getWorkspaceTabSubWindowsOptions()[i]); } if (m_workspaces.size() <= 0) { // cannot go further if there are no workspaces @@ -1283,8 +1394,10 @@ void MainWindow::loadConfiguration(const Configuration *configuration, bool from } // Device sets - if (waitBox) { - waitBox->setInformativeText("Loading device sets..."); + if (waitBox) + { + waitBox->setLabelText("Loading device sets..."); + waitBox->setValue(25); } const QList& deviceSetPresets = configuration->getDeviceSetPresets(); @@ -1354,11 +1467,17 @@ void MainWindow::loadConfiguration(const Configuration *configuration, bool from m_deviceUIs.back()->m_deviceGUI->restoreGeometry(deviceSetPreset.getDeviceGeometry()); m_deviceUIs.back()->m_mainSpectrumGUI->restoreGeometry(deviceSetPreset.getSpectrumGeometry()); m_deviceUIs.back()->loadDeviceSetSettings(&deviceSetPreset, m_pluginManager->getPluginAPI(), &m_workspaces, nullptr); + + if (waitBox) { + waitBox->setValue(waitBox->value() + 50/deviceSetPresets.size()); + } } // Features - if (waitBox) { - waitBox->setInformativeText("Loading device sets..."); + if (waitBox) + { + waitBox->setLabelText("Loading feature sets..."); + waitBox->setValue(75); } m_featureUIs[0]->loadFeatureSetSettings( @@ -1381,8 +1500,10 @@ void MainWindow::loadConfiguration(const Configuration *configuration, bool from } // Lastly restore workspaces geometry - if (waitBox) { - waitBox->setInformativeText("Finalizing..."); + if (waitBox) + { + waitBox->setValue(90); + waitBox->setLabelText("Finalizing..."); } for (int i = 0; i < configuration->getNumberOfWorkspaceGeometries(); i++) @@ -1390,12 +1511,16 @@ void MainWindow::loadConfiguration(const Configuration *configuration, bool from m_workspaces[i]->restoreGeometry(configuration->getWorkspaceGeometries()[i]); m_workspaces[i]->restoreGeometry(configuration->getWorkspaceGeometries()[i]); m_workspaces[i]->adjustSubWindowsAfterRestore(); +#ifdef ANDROID + // On Android, workspaces seem to be restored to 0,20, rather than 0,0 + m_workspaces[i]->move(m_workspaces[i]->pos().x(), 0); + // Need to call updateGeometry, otherwise sometimes the layout is corrupted + m_workspaces[i]->updateGeometry(); +#endif } - if (waitBox) - { - waitBox->close(); - delete waitBox; + if (waitBox) { + waitBox->setValue(100); } } @@ -1430,6 +1555,7 @@ void MainWindow::saveConfiguration(Configuration *configuration) { configuration->getWorkspaceGeometries().push_back(workspace->saveGeometry()); configuration->getWorkspaceAutoStackOptions().push_back(workspace->getAutoStackOption()); + configuration->getWorkspaceTabSubWindowsOptions().push_back(workspace->getTabSubWindowsOption()); } } @@ -1461,24 +1587,46 @@ QString MainWindow::openGLVersion() } } -void MainWindow::createMenuBar() +void MainWindow::createMenuBar(QToolButton *button) { - QMenuBar *menuBar = this->menuBar(); + QMenu *fileMenu, *viewMenu, *workspacesMenu, *preferencesMenu, *helpMenu; + + if (button == nullptr) + { + QMenuBar *menuBar = this->menuBar(); + fileMenu = menuBar->addMenu("&File"); + viewMenu = menuBar->addMenu("&View"); + workspacesMenu = menuBar->addMenu("&Workspaces"); + preferencesMenu = menuBar->addMenu("&Preferences"); + helpMenu = menuBar->addMenu("&Help"); + } + else + { + QMenu *menu = new QMenu(); + fileMenu = new QMenu("&File"); + menu->addMenu(fileMenu); + viewMenu = new QMenu("&View"); + menu->addMenu(viewMenu); + workspacesMenu = new QMenu("&Workspaces"); + menu->addMenu(workspacesMenu); + preferencesMenu = new QMenu("&Preferences"); + menu->addMenu(preferencesMenu); + helpMenu = new QMenu("&Help"); + menu->addMenu(helpMenu); + button->setMenu(menu); + } - QMenu *fileMenu = menuBar->addMenu("&File"); QAction *exitAction = fileMenu->addAction("E&xit"); exitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); exitAction->setToolTip("Exit"); QObject::connect(exitAction, &QAction::triggered, this, &QMainWindow::close); - QMenu *viewMenu = menuBar->addMenu("&View"); QAction *fullscreenAction = viewMenu->addAction("&Fullscreen"); fullscreenAction->setShortcut(QKeySequence(Qt::Key_F11)); fullscreenAction->setToolTip("Toggle fullscreen view"); fullscreenAction->setCheckable(true); QObject::connect(fullscreenAction, &QAction::triggered, this, &MainWindow::on_action_View_Fullscreen_toggled); - QMenu *workspacesMenu = menuBar->addMenu("&Workspaces"); QAction *newWorkspaceAction = workspacesMenu->addAction("&New"); newWorkspaceAction->setToolTip("Add a new workspace"); QObject::connect(newWorkspaceAction, &QAction::triggered, this, &MainWindow::addWorkspace); @@ -1489,7 +1637,6 @@ void MainWindow::createMenuBar() removeEmptyWorkspacesAction->setToolTip("Remove empty workspaces"); QObject::connect(removeEmptyWorkspacesAction, &QAction::triggered, this, &MainWindow::removeEmptyWorkspaces); - QMenu *preferencesMenu = menuBar->addMenu("&Preferences"); QAction *configurationsAction = preferencesMenu->addAction("&Configurations..."); configurationsAction->setToolTip("Manage configurations"); QObject::connect(configurationsAction, &QAction::triggered, this, &MainWindow::on_action_Configurations_triggered); @@ -1519,7 +1666,6 @@ void MainWindow::createMenuBar() saveAllAction->setToolTip("Save all current settings"); QObject::connect(saveAllAction, &QAction::triggered, this, &MainWindow::on_action_saveAll_triggered); - QMenu *helpMenu = menuBar->addMenu("&Help"); QAction *quickStartAction = helpMenu->addAction("&Quick start..."); quickStartAction->setToolTip("Instructions for quick start"); QObject::connect(quickStartAction, &QAction::triggered, this, &MainWindow::on_action_Quick_Start_triggered); @@ -1882,7 +2028,11 @@ void MainWindow::handleWorkspaceVisibility(Workspace *workspace, bool visibility void MainWindow::addWorkspace() { int workspaceIndex = m_workspaces.size(); - m_workspaces.push_back(new Workspace(workspaceIndex)); + Workspace *workspace = new Workspace(workspaceIndex); + m_workspaces.push_back(workspace); + if (workspace->getMenuButton()) { + createMenuBar(workspace->getMenuButton()); + } QStringList featureNames; m_pluginManager->listFeatures(featureNames); m_workspaces.back()->addAvailableFeatures(featureNames); @@ -1923,6 +2073,13 @@ void MainWindow::addWorkspace() &MainWindow::openFeaturePresetsDialog ); + QObject::connect( + m_workspaces.back(), + &Workspace::configurationPresetsDialogRequested, + this, + &MainWindow::on_action_Configurations_triggered + ); + QObject::connect( m_workspaces.back(), &Workspace::startAllDevices, @@ -1951,7 +2108,7 @@ void MainWindow::addWorkspace() // tabBars.back()->setStyleSheet("QTabBar::tab:selected { background: rgb(128,70,0); }"); // change text color so it is visible // } } -} + } void MainWindow::viewAllWorkspaces() { @@ -2006,6 +2163,13 @@ void MainWindow::removeEmptyWorkspaces() } } } + +#ifdef ANDROID + // Need at least one workspace on Android, as no menus without + if (m_workspaces.size() == 0) { + addWorkspace(); + } +#endif } void MainWindow::on_action_View_Fullscreen_toggled(bool checked) @@ -2063,7 +2227,12 @@ void MainWindow::on_action_Loaded_Plugins_triggered() void MainWindow::on_action_Configurations_triggered() { - ConfigurationsDialog dialog(this); + openConfigurationDialog(false); +} + +void MainWindow::openConfigurationDialog(bool openOnly) +{ + ConfigurationsDialog dialog(openOnly, this); dialog.setConfigurations(m_mainCore->m_settings.getConfigurations()); dialog.populateTree(); QObject::connect( @@ -2078,24 +2247,28 @@ void MainWindow::on_action_Configurations_triggered() this, [=](const Configuration* configuration) { this->loadConfiguration(configuration, true); } ); + new DialogPositioner(&dialog, true); dialog.exec(); } void MainWindow::on_action_Audio_triggered() { AudioDialogX audioDialog(m_dspEngine->getAudioDeviceManager(), this); + new DialogPositioner(&audioDialog, true); audioDialog.exec(); } void MainWindow::on_action_Graphics_triggered() { GraphicsDialog graphicsDialog(m_mainCore->m_settings, this); + new DialogPositioner(&graphicsDialog, true); graphicsDialog.exec(); } void MainWindow::on_action_Logging_triggered() { LoggingDialog loggingDialog(m_mainCore->m_settings, this); + new DialogPositioner(&loggingDialog, true); loggingDialog.exec(); m_mainCore->setLoggingOptions(); } @@ -2103,6 +2276,7 @@ void MainWindow::on_action_Logging_triggered() void MainWindow::on_action_My_Position_triggered() { MyPositionDialog myPositionDialog(m_mainCore->m_settings, this); + new DialogPositioner(&myPositionDialog, true); myPositionDialog.exec(); } @@ -2110,6 +2284,7 @@ void MainWindow::on_action_DeviceUserArguments_triggered() { qDebug("MainWindow::on_action_DeviceUserArguments_triggered"); DeviceUserArgsDialog deviceUserArgsDialog(DeviceEnumerator::instance(), m_mainCore->m_settings.getDeviceUserArgs(), this); + new DialogPositioner(&deviceUserArgsDialog, true); deviceUserArgsDialog.exec(); } @@ -2121,6 +2296,7 @@ void MainWindow::on_action_commands_triggered() commandsDialog.setApiPort(m_apiServer->getPort()); commandsDialog.setCommandKeyReceiver(m_commandKeyReceiver); commandsDialog.populateTree(); + new DialogPositioner(&commandsDialog, true); commandsDialog.exec(); } @@ -2140,6 +2316,7 @@ void MainWindow::on_action_FFT_triggered() this, SLOT(fftWisdomProcessFinished(int, QProcess::ExitStatus))); FFTWisdomDialog fftWisdomDialog(m_fftWisdomProcess, this); + new DialogPositioner(&fftWisdomDialog, true); if (fftWisdomDialog.exec() == QDialog::Rejected) { @@ -2790,6 +2967,7 @@ void MainWindow::openFeaturePresetsDialog(QPoint p, Workspace *workspace) dialog.setWorkspaces(&m_workspaces); dialog.populateTree(); dialog.move(p); + new DialogPositioner(&dialog, true); dialog.exec(); if (dialog.wasPresetLoaded()) @@ -2820,6 +2998,7 @@ void MainWindow::openDeviceSetPresetsDialog(QPoint p, DeviceGUI *deviceGUI) dialog.setWorkspaces(&m_workspaces); dialog.populateTree((int) deviceGUI->getDeviceType()); dialog.move(p); + new DialogPositioner(&dialog, true); dialog.exec(); } @@ -2840,7 +3019,9 @@ void MainWindow::on_action_About_triggered() void MainWindow::updateStatus() { - m_dateTimeWidget->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss t")); + if (m_dateTimeWidget) { + m_dateTimeWidget->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss t")); + } } void MainWindow::commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release) @@ -2862,3 +3043,30 @@ void MainWindow::commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifie } } } + +void MainWindow::keyPressEvent(QKeyEvent* event) +{ +#ifdef ANDROID + if (event->key() == Qt::Key_Back) + { + // On Android, we don't want to exit when back key is pressed, just run in the background + Android::moveTaskToBack(); + } + else +#endif + { + QMainWindow::keyPressEvent(event); + } +} + +void MainWindow::orientationChanged(Qt::ScreenOrientation orientation) +{ +#ifdef ANDROID + // Adjust workspace tab position, to leave max space for MDI windows + if ((orientation == Qt::LandscapeOrientation) || (orientation == Qt::InvertedLandscapeOrientation)) { + setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::West); + } else { + setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::South); + } +#endif +} diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index 102a5e861..6243a241f 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -34,6 +34,7 @@ class QLabel; class QTreeWidgetItem; class QDir; +class QToolButton; class DSPEngine; class DSPDeviceSourceEngine; @@ -136,7 +137,7 @@ private: void saveFeatureSetPresetSettings(FeatureSetPreset* preset, int featureSetIndex); QString openGLVersion(); - void createMenuBar(); + void createMenuBar(QToolButton *button); void createStatusBar(); void closeEvent(QCloseEvent*); void applySettings(); @@ -171,6 +172,9 @@ private: bool handleMessage(const Message& cmd); +protected: + virtual void keyPressEvent(QKeyEvent* event) override; + private slots: void handleMessages(); void handleWorkspaceVisibility(Workspace *workspace, bool visibility); @@ -194,6 +198,8 @@ private slots: void addWorkspace(); void viewAllWorkspaces(); void removeEmptyWorkspaces(); + void openConfigurationDialog(bool openOnly); + void loadDefaultConfigurations(); void loadConfiguration(const Configuration *configuration, bool fromDialog = false); void saveConfiguration(Configuration *configuration); void sampleSourceAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex); @@ -215,6 +221,7 @@ private slots: void openDeviceSetPresetsDialog(QPoint p, DeviceGUI *deviceGUI); void commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release); void fftWisdomProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + void orientationChanged(Qt::ScreenOrientation orientation); }; #endif // INCLUDE_MAINWINDOW_H diff --git a/settings/configurations/airspyhf/radioclockeu.cfgx b/settings/configurations/airspyhf/radioclockeu.cfgx new file mode 100644 index 000000000..57c6936da --- /dev/null +++ b/settings/configurations/airspyhf/radioclockeu.cfgx @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/settings/configurations/rtlsdr/adsb.cfgx b/settings/configurations/rtlsdr/adsb.cfgx new file mode 100644 index 000000000..56fbbe0ca --- /dev/null +++ b/settings/configurations/rtlsdr/adsb.cfgx @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/settings/configurations/rtlsdr/ais.cfgx b/settings/configurations/rtlsdr/ais.cfgx new file mode 100644 index 000000000..245c71d2d --- /dev/null +++ b/settings/configurations/rtlsdr/ais.cfgx @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/settings/configurations/rtlsdr/apt.cfgx b/settings/configurations/rtlsdr/apt.cfgx new file mode 100644 index 000000000..a321e5772 --- /dev/null +++ b/settings/configurations/rtlsdr/apt.cfgx @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/settings/configurations/rtlsdr/dab.cfgx b/settings/configurations/rtlsdr/dab.cfgx new file mode 100644 index 000000000..651b9f1c7 --- /dev/null +++ b/settings/configurations/rtlsdr/dab.cfgx @@ -0,0 +1 @@ +kAABAXABB1JUTCBTRFJwAgNEQUKAAxuQAAEBcAEHZGVmYXVsdHACB25vIG5hbWUAZAAAZAEBgGVCAdnQywADAAAAAAAAAAAAAAAAAZoAAAMlAAAAAAAAAAAAAAGaAAADJQAAAAAAAAAAAZsAAAAAAAAAAAAAAZoAAAMlAMgBAYHJBB2QAAEBcAEHZGVmYXVsdHACB25vIG5hbWUwAwQNcx2AgAQAgAXikAABAQABAgQAAAIAAAMBBEAEBAAAAABABQRCjAAAYAYBAWAHAQFgCAEAYAkBAAAKAQFgCwEBAA0BEgAOAQEADwEeYBABAQARATJAEgQ/KPXDABMBAQAUAQpgFQEAcBYJMTI3LjAuMC4xEBcCIrdgGAEAYBkBAQAaATJgGwEAABwBAmAdAQAAHgBgHwEAACABA3AhBUFuZ2VsACIBAgAjAAAkAicQACUCJxAAJgInEAAnAQVgKgEBACsBBQAsAQEALQEBAC4AYC8BAGAwAQAAZAAAbgCAKAQAAAAAgCkEAAAAAGAGAQEABwBgCAEBgAlCAdnQywADAAAAABOIAAAAAAAAFQMAAAFuAAATiAAAAAAAABUDAAABbv////8AAAAAAZsAABOIAAAAAAAAFQMAAAFuAAoAgAtCAdnQywADAAAAABOIAAAAAAAAFPMAAAEEAAATiAAAAAAAABTzAAABBP////8AAAAAAZsAABOIAAAAAAAAFPMAAAEEAAwAcA0cc2RyYW5nZWwuc2FtcGxlc291cmNlLnJ0bHNkcnAOCDAwMDAwMDAxAA8AABAAABQBAXAYHHNkcmFuZ2VsLnNhbXBsZXNvdXJjZS5ydGxzZHJwGQgwMDAwMDAwMQAaAIAbXpAAAQEAAgIBpAADABAEAGAFAQBgBgEAAAcBAgAIAx9AAGAJAQBgCgEAYAsBAGAMAQAgDQAQDgMmJaBgDwEAYBABAHARCTEyNy4wLjAuMRASAiK4EBMAYBQBAWAVAQAAyAEBcMkZc2RyYW5nZWwuY2hhbm5lbC5kYWJkZW1vZIHKAZWQAAEBAAEAAAIAcAMAQAQESbufQEAFBECgAABgBgEAcAcVU3lzdGVtIGRlZmF1bHQgZGV2aWNlgAgjkAABAQABABACBP9NaRlwAw9EQUIgRGVtb2R1bGF0b3IABwAQCQT/TWkZcAoPREFCIERlbW9kdWxhdG9yYAsBAHAMCTEyNy4wLjAuMRANAiK4EA4AEA8AgBCeAAAA/wAAAAAAAAAEAAAAIgBzAGUAdAB0AGkAbgBnAHMAQwBvAG4AdABhAGkAbgBlAHIAAAABAAAAIABwAHIAbwBnAHIAYQBtAEMAbwBuAHQAYQBpAG4AZQByAAAAAQAAABwAYwB1AHIAcgBlAG4AdABQAHIAbwBnAHIAYQBtAAAAAQAAABQAcwB0AGEAdABpAHMAdABpAGMAcwAAAAEAEQCAEkIB2dDLAAMAAAAAAAAAAAAAAAABmgAAAvwAAAAAAAAAAP////7////+AAAAAAIAAAABmwAAAAAAAAAAAAABmgAAAvxgEwEAAGQAAGUBAQBmAQIAyAH/AMkB/wDKAf8EASwBAWQBLQEABAGQAQFkAZEBAQ== \ No newline at end of file diff --git a/settings/configurations/rtlsdr/isspacket.cfgx b/settings/configurations/rtlsdr/isspacket.cfgx new file mode 100644 index 000000000..88343baf2 --- /dev/null +++ b/settings/configurations/rtlsdr/isspacket.cfgx @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/settings/configurations/rtlsdr/radiosonde.cfgx b/settings/configurations/rtlsdr/radiosonde.cfgx new file mode 100644 index 000000000..2adbb104f --- /dev/null +++ b/settings/configurations/rtlsdr/radiosonde.cfgx @@ -0,0 +1 @@ +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BBAAAE4gAAAAAAAAU8wAAAQT/////AAAAAAGbAAATiAAAAAAAABTzAAABBAAMAHANHHNkcmFuZ2VsLnNhbXBsZXNvdXJjZS5ydGxzZHJwDggwMDAwMDAwMQAPAAAQAAAUAQFwGBxzZHJhbmdlbC5zYW1wbGVzb3VyY2UucnRsc2RycBkIMDAwMDAwMDEAGgCAG1+QAAEBAAICAaQAAwAQBAECYAUBAGAGAQAABwECAAgDD0JAYAkBAGAKAQBgCwEAYAwBACANABAOAyYloGAPAQBgEAEAcBEJMTI3LjAuMC4xEBICIrgQEwBgFAEBYBUBAADIAQFwySBzZHJhbmdlbC5jaGFubmVsLnJhZGlvc29uZGVkZW1vZIHKAyaQAAEBAAEDAYagQAIERhYAAEADBEUWAABABARD4QAAcAUAYAYBAHAHCTEyNy4wLjAuMRAIAicPAAoBBQALAQYQDAT/ZgBmcA0WUmFkaW9zb25kZSBEZW1vZHVsYXRvcoAOLZAAAQEAAQMBhqAQAgT/ZgBmcAMWUmFkaW9zb25kZSBEZW1vZHVsYXRvcgAHAAAPAGAQAQBwEQkxMjcuMC4wLjEQEgIiuBATABAUAIAVupAAAQEAAQEBAAIBMgADAQoABAEBAAYBAQAUAEAVBD+AAABAFgQAAAAAABgAABkAQBoEP4AAAEAbBD+AAABAHAQ+gICBEB0AACQBAUAlBD+AAABAJgQAAAAAACgAACkAQCoEP4AAAEArBD+AAABALAQ+gICBEC0AEAoBAhDIAQEAyQEwANIAANMAYNQBAWDVAQAA1gEKANcAANgAANkAQNoEAAAAAEDbBD+AAABA3AQAAAAAEN0BARDeAHAWEnJhZGlvc29uZGVfbG9nLmNzdmAXAQAAGAISwIAZgAAAAP8AAAAAAAAAAwAAACIAcwBlAHQAdABpAG4AZwBzAEMAbwBuAHQAYQBpAG4AZQByAAAAAQAAAB4AZgByAGEAbQBlAHMAQwBvAG4AdABhAGkAbgBlAHIAAAABAAAAHABzAGMAbwBwAGUAQwBvAG4AdABhAGkAbgBlAHIAAAAAABoAgBtCAdnQywADAAAAABOIAAAAAAAAFSIAAAMHAAATiAAAAAAAABUiAAADB/////8AAAAAAZsAABOIAAAAAAAAFSIAAAMHYBwBAABkAABlAQEAZgECAGcBAwBoAQQAaQEFAGoBBgBrAQcAbAEIAG0BCQBuAQoAbwELAHABDABxAQ0AcgEOAHMBDwB0ARAAdQERAHYBEgB3ARMAeAEUAHkBFQB6ARYAewEXAHwBGAB9ARkAyAH/AMkB/wDKAf8AywH/AMwB/wDNAf8AzgH/AM8B/wDQAf8A0QH/ANIB/wDTAf8A1AH/ANUB/wDWAf8A1wH/ANgB/wDZAf8A2gH/ANsB/wDcAf8A3QH/AN4B/wDfAf8A4AH/AOEB/wQBLAEBZAEtAQAEAZABAWQBkQEB \ No newline at end of file diff --git a/settings/presets/rtlsdr/noaa18.prex b/settings/presets/rtlsdr/noaa18.prex new file mode 100644 index 000000000..a573be397 --- /dev/null +++ b/settings/presets/rtlsdr/noaa18.prex @@ -0,0 +1 @@ +kAABAXABB1JUTCBTRFJwAgdOT0FBIDE4MAMECDgI0IAEAIEFAWmQAAEBAAECBAAAAgAAAwEEQAQEAAAAAEAFBEKMAABgBgEBYAcBAWAIAQBgCQEAAAoBAWALAQEADQESAA4BAQAPAR5gEAEBABEBMkASBD8o9cMAEwEBABQBCmAVAQBwFgkxMjcuMC4wLjEQFwIit2AYAQBgGQEBABoBMmAbAQAAHAECYB0BAAAeAGAfAQAAIAEDcCEFQW5nZWwAIgECACMAACQCJxAAJQInEAAmAicQACcBBWAqAQEAKwEFACwBAQAtAQEALgBgLwEAYDABAABkAABuAIAoiwAAAAMAAAAACDOcAAAAnEAB//8rKzY2//8AAAAAAAMAAAAOAE4ATwBBAEEAIAAxADUAAAAACDgQoAAAnEAB//8rKzY2//8AAAAAAAMAAAAOAE4ATwBBAEEAIAAxADgAAAAACCuswAAAnEAB//8rKzY2//8AAAAAAAMAAAAOAE4ATwBBAEEAIAAxADmAKQQAAAAAYAYBAQAHAGAIAQGACUIB2dDLAAMAAAAAE4gAAAAAAAAVAwAAAW4AABOIAAAAAAAAFQMAAAFu/////wAAAAABmwAAE4gAAAAAAAAVAwAAAW4ACgCAC0IB2dDLAAMAAAAAAAAAAAAAAAABfwAAARAAAAAAAAAAFAAAAWsAAAEYAAAAAAIAAAABmwAAAAAAAAAAAAABfwAAARAADABwDRxzZHJhbmdlbC5zYW1wbGVzb3VyY2UucnRsc2RycA4IMDAwMDAwMDEADwAAEAAAFAEBcBgcc2RyYW5nZWwuc2FtcGxlc291cmNlLnJ0bHNkcnAZCDAwMDAwMDAxABoAgBtfkAABAQACAgGkAAMAEAQBA2AFAQBgBgEAAAcBAgAIAw9CQGAJAQBgCgEAYAsBAGAMAQAgDQAQDgMmJaBgDwEAYBABAHARCTEyNy4wLjAuMRASAiK4EBMAYBQBAWAVAQAAyAEBcMkZc2RyYW5nZWwuY2hhbm5lbC5hcHRkZW1vZIHKAYmQAAEBAAECVfAAAgBAAwRHHEAAQAQERoTQAGAFAQBgBgEBYAcBAGAIAQBgCQEAYAoBAAALAGAMAQBgDQEBcA4DQWxsYA8BAHAQAAARAgDIYBIBAAATARSAFCWQAAEBAAECVfAQAgT/2HCpcAMPQVBUIERlbW9kdWxhdG9yAAcAEBUE/9hwqXAWD0FQVCBEZW1vZHVsYXRvcmAXAQBwGAkxMjcuMC4wLjEQGQIiuBAaABAbAIAcWgAAAP8AAAAAAAAAAgAAACIAcwBlAHQAdABpAG4AZwBzAEMAbwBuAHQAYQBpAG4AZQByAAAAAQAAABwAaQBtAGEAZwBlAEMAbwBuAHQAYQBpAG4AZQByAAAAAWAdAQFgHgEAAB8BZAAgAgDIcCEAACIAACMBCgAkARRAJQQAAAAAQCYEAAAAAAAnAIAoQgHZ0MsAAwAAAAATiAAAAAAAABUiAAADBwAAE4gAAAAAAAAVIgAAAwf/////AAAAAAGbAAATiAAAAAAAABUiAAADB2ApAQA= \ No newline at end of file diff --git a/settings/presets/rtlsdr/noaa19.prex b/settings/presets/rtlsdr/noaa19.prex new file mode 100644 index 000000000..b46443219 --- /dev/null +++ b/settings/presets/rtlsdr/noaa19.prex @@ -0,0 +1 @@ +kAABAXABB1JUTCBTRFJwAgdOT0FBIDE5MAMECCuk8IAEAIEFAWmQAAEBAAECBAAAAgAAAwEEQAQEAAAAAEAFBEKMAABgBgEBYAcBAWAIAQBgCQEAAAoBAWALAQEADQESAA4BAQAPAR5gEAEBABEBMkASBD8o9cMAEwEBABQBCmAVAQBwFgkxMjcuMC4wLjEQFwIit2AYAQBgGQEBABoBMmAbAQAAHAECYB0BAAAeAGAfAQAAIAEDcCEFQW5nZWwAIgECACMAACQCJxAAJQInEAAmAicQACcBBWAqAQEAKwEFACwBAQAtAQEALgBgLwEAYDABAABkAABuAIAoiwAAAAMAAAAACDOcAAAAnEAB//8rKzY2//8AAAAAAAMAAAAOAE4ATwBBAEEAIAAxADUAAAAACDgQoAAAnEAB//8rKzY2//8AAAAAAAMAAAAOAE4ATwBBAEEAIAAxADgAAAAACCuswAAAnEAB//8rKzY2//8AAAAAAAMAAAAOAE4ATwBBAEEAIAAxADmAKQQAAAAAYAYBAQAHAGAIAQGACUIB2dDLAAMAAAAAE4gAAAAAAAAVAwAAAW4AABOIAAAAAAAAFQMAAAFu/////wAAAAABmwAAE4gAAAAAAAAVAwAAAW4ACgCAC0IB2dDLAAMAAAAAAAAAAAAAAAABfwAAARAAAAAAAAAAFAAAAWsAAAEYAAAAAAIAAAABmwAAAAAAAAAAAAABfwAAARAADABwDRxzZHJhbmdlbC5zYW1wbGVzb3VyY2UucnRsc2RycA4IMDAwMDAwMDEADwAAEAAAFAEBcBgcc2RyYW5nZWwuc2FtcGxlc291cmNlLnJ0bHNkcnAZCDAwMDAwMDAxABoAgBtfkAABAQACAgGkAAMAEAQBA2AFAQBgBgEAAAcBAgAIAw9CQGAJAQBgCgEAYAsBAGAMAQAgDQAQDgMmJaBgDwEAYBABAHARCTEyNy4wLjAuMRASAiK4EBMAYBQBAWAVAQAAyAEBcMkZc2RyYW5nZWwuY2hhbm5lbC5hcHRkZW1vZIHKAYmQAAEBAAECVfAAAgBAAwRHHEAAQAQERoTQAGAFAQBgBgEBYAcBAGAIAQBgCQEAYAoBAAALAGAMAQBgDQEBcA4DQWxsYA8BAHAQAAARAgDIYBIBAAATARSAFCWQAAEBAAECVfAQAgT/2HCpcAMPQVBUIERlbW9kdWxhdG9yAAcAEBUE/9hwqXAWD0FQVCBEZW1vZHVsYXRvcmAXAQBwGAkxMjcuMC4wLjEQGQIiuBAaABAbAIAcWgAAAP8AAAAAAAAAAgAAACIAcwBlAHQAdABpAG4AZwBzAEMAbwBuAHQAYQBpAG4AZQByAAAAAQAAABwAaQBtAGEAZwBlAEMAbwBuAHQAYQBpAG4AZQByAAAAAWAdAQFgHgEAAB8BZAAgAgDIcCEAACIAACMBCgAkARRAJQQAAAAAQCYEAAAAAAAnAIAoQgHZ0MsAAwAAAAATiAAAAAAAABUiAAADBwAAE4gAAAAAAAAVIgAAAwf/////AAAAAAGbAAATiAAAAAAAABUiAAADB2ApAQA= \ No newline at end of file diff --git a/settings/settings.qrc b/settings/settings.qrc new file mode 100644 index 000000000..b9a99934b --- /dev/null +++ b/settings/settings.qrc @@ -0,0 +1,13 @@ + + + configurations/rtlsdr/adsb.cfgx + configurations/rtlsdr/ais.cfgx + configurations/rtlsdr/apt.cfgx + configurations/rtlsdr/dab.cfgx + configurations/rtlsdr/isspacket.cfgx + configurations/rtlsdr/radiosonde.cfgx + configurations/airspyhf/radioclockeu.cfgx + presets/rtlsdr/noaa18.prex + presets/rtlsdr/noaa19.prex + +