From d404e9f94398c141b2744a06715c5ec56087b41e Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sat, 27 Aug 2022 10:18:17 +0100 Subject: [PATCH] Add start/stop all devices button in toolbar. Add device stateChanged signal. Use in RTL SDR GUI for updating device state --- plugins/samplesource/rtlsdr/rtlsdrgui.cpp | 44 ++++++------- plugins/samplesource/rtlsdr/rtlsdrgui.h | 2 - sdrbase/device/deviceapi.cpp | 14 ++++ sdrbase/device/deviceapi.h | 6 ++ sdrbase/dsp/dspdevicemimoengine.cpp | 46 +++++++++---- sdrbase/dsp/dspdevicemimoengine.h | 5 ++ sdrbase/dsp/dspdevicesinkengine.cpp | 23 +++++-- sdrbase/dsp/dspdevicesinkengine.h | 4 ++ sdrbase/dsp/dspdevicesourceengine.cpp | 23 +++++-- sdrbase/dsp/dspdevicesourceengine.h | 4 ++ sdrbase/maincore.h | 1 + sdrgui/gui/workspace.cpp | 79 ++++++++++++++++++++++- sdrgui/gui/workspace.h | 7 ++ sdrgui/mainwindow.cpp | 71 ++++++++++++++++++++ sdrgui/mainwindow.h | 3 + 15 files changed, 276 insertions(+), 56 deletions(-) diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp index 5118993f9..266e93a72 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp @@ -39,8 +39,7 @@ RTLSDRGui::RTLSDRGui(DeviceUISet *deviceUISet, QWidget* parent) : m_forceSettings(true), m_settings(), m_sampleRateMode(true), - m_sampleSource(0), - m_lastEngineState(DeviceAPI::StNotStarted) + m_sampleSource(0) { m_deviceUISet = deviceUISet; setAttribute(Qt::WA_DeleteOnClose, true); @@ -60,8 +59,8 @@ RTLSDRGui::RTLSDRGui(DeviceUISet *deviceUISet, QWidget* parent) : connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &))); connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware())); - connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); - m_statusTimer.start(500); + connect(deviceUISet->m_deviceAPI, &DeviceAPI::stateChanged, this, &RTLSDRGui::updateStatus); + updateStatus(); displaySettings(); makeUIConnections(); @@ -426,28 +425,23 @@ void RTLSDRGui::updateStatus() { int state = m_deviceUISet->m_deviceAPI->state(); - if(m_lastEngineState != state) + switch(state) { - switch(state) - { - case DeviceAPI::StNotStarted: - ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); - break; - case DeviceAPI::StIdle: - ui->startStop->setStyleSheet("QToolButton { background-color : blue; }"); - break; - case DeviceAPI::StRunning: - ui->startStop->setStyleSheet("QToolButton { background-color : green; }"); - break; - case DeviceAPI::StError: - ui->startStop->setStyleSheet("QToolButton { background-color : red; }"); - QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage()); - break; - default: - break; - } - - m_lastEngineState = state; + case DeviceAPI::StNotStarted: + ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); + break; + case DeviceAPI::StIdle: + ui->startStop->setStyleSheet("QToolButton { background-color : blue; }"); + break; + case DeviceAPI::StRunning: + ui->startStop->setStyleSheet("QToolButton { background-color : green; }"); + break; + case DeviceAPI::StError: + ui->startStop->setStyleSheet("QToolButton { background-color : red; }"); + QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage()); + break; + default: + break; } } diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.h b/plugins/samplesource/rtlsdr/rtlsdrgui.h index 09a26f3cd..5ae19e56e 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.h +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.h @@ -58,12 +58,10 @@ private: RTLSDRSettings m_settings; bool m_sampleRateMode; //!< true: device, false: base band sample rate update mode QTimer m_updateTimer; - QTimer m_statusTimer; std::vector m_gains; RTLSDRInput* m_sampleSource; int m_sampleRate; quint64 m_deviceCenterFrequency; //!< Center frequency in device - int m_lastEngineState; MessageQueue m_inputMessageQueue; void displayGains(); diff --git a/sdrbase/device/deviceapi.cpp b/sdrbase/device/deviceapi.cpp index e6da31bae..e019bbd3a 100644 --- a/sdrbase/device/deviceapi.cpp +++ b/sdrbase/device/deviceapi.cpp @@ -51,6 +51,15 @@ DeviceAPI::DeviceAPI( m_deviceSinkEngine(deviceSinkEngine), m_deviceMIMOEngine(deviceMIMOEngine) { + if (m_deviceSourceEngine) { + QObject::connect(m_deviceSourceEngine, &DSPDeviceSourceEngine::stateChanged, this, &DeviceAPI::engineStateChanged); + } + if (m_deviceSinkEngine) { + QObject::connect(m_deviceSinkEngine, &DSPDeviceSinkEngine::stateChanged, this, &DeviceAPI::engineStateChanged); + } + if (m_deviceMIMOEngine) { + QObject::connect(m_deviceMIMOEngine, &DSPDeviceMIMOEngine::stateChanged, this, &DeviceAPI::engineStateChanged); + } } DeviceAPI::~DeviceAPI() @@ -826,3 +835,8 @@ void DeviceAPI::setDeviceSetIndex(int deviceSetIndex) m_deviceTabIndex = deviceSetIndex; renumerateChannels(); } + +void DeviceAPI::engineStateChanged() +{ + emit stateChanged(this); +} diff --git a/sdrbase/device/deviceapi.h b/sdrbase/device/deviceapi.h index f2477b10b..a351913af 100644 --- a/sdrbase/device/deviceapi.h +++ b/sdrbase/device/deviceapi.h @@ -212,5 +212,11 @@ protected: private: void renumerateChannels(); + +private slots: + void engineStateChanged(); + +signals: + void stateChanged(DeviceAPI *deviceAPI); }; #endif // SDRBASE_DEVICE_DEVICEAPI_H_ diff --git a/sdrbase/dsp/dspdevicemimoengine.cpp b/sdrbase/dsp/dspdevicemimoengine.cpp index 3c4a8ce64..1eab2b7ac 100644 --- a/sdrbase/dsp/dspdevicemimoengine.cpp +++ b/sdrbase/dsp/dspdevicemimoengine.cpp @@ -61,11 +61,29 @@ DSPDeviceMIMOEngine::~DSPDeviceMIMOEngine() wait(); } +void DSPDeviceMIMOEngine::setStateRx(State state) +{ + if (m_stateRx != state) + { + m_stateRx = state; + emit stateChanged(); + } +} + +void DSPDeviceMIMOEngine::setStateTx(State state) +{ + if (m_stateTx != state) + { + m_stateTx = state; + emit stateChanged(); + } +} + void DSPDeviceMIMOEngine::run() { qDebug() << "DSPDeviceMIMOEngine::run"; - m_stateRx = StIdle; - m_stateTx = StIdle; + setStateRx(StIdle); + setStateTx(StIdle); exec(); } @@ -80,8 +98,8 @@ void DSPDeviceMIMOEngine::stop() qDebug() << "DSPDeviceMIMOEngine::stop"; gotoIdle(0); // Rx gotoIdle(1); // Tx - m_stateRx = StNotStarted; - m_stateTx = StNotStarted; + setStateRx(StNotStarted); + setStateTx(StNotStarted); QThread::exit(); } @@ -763,12 +781,12 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoError(int subsystemIndex, co if (subsystemIndex == 0) { m_errorMessageRx = errorMessage; - m_stateRx = StError; + setStateRx(StError); } else if (subsystemIndex == 1) { m_errorMessageTx = errorMessage; - m_stateTx = StError; + setStateTx(StError); } return StError; @@ -881,10 +899,10 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages() if (DSPAcquisitionInit::match(*message)) { - m_stateRx = gotoIdle(0); + setStateRx(gotoIdle(0)); if (m_stateRx == StIdle) { - m_stateRx = gotoInit(0); // State goes ready if init is performed + setStateRx(gotoInit(0)); // State goes ready if init is performed } returnState = m_stateRx; @@ -892,22 +910,22 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages() else if (DSPAcquisitionStart::match(*message)) { if (m_stateRx == StReady) { - m_stateRx = gotoRunning(0); + setStateRx(gotoRunning(0)); } returnState = m_stateRx; } else if (DSPAcquisitionStop::match(*message)) { - m_stateRx = gotoIdle(0); + setStateRx(gotoIdle(0)); returnState = m_stateRx; } else if (DSPGenerationInit::match(*message)) { - m_stateTx = gotoIdle(1); + setStateTx(gotoIdle(1)); if (m_stateTx == StIdle) { - m_stateTx = gotoInit(1); // State goes ready if init is performed + setStateTx(gotoInit(1)); // State goes ready if init is performed } returnState = m_stateTx; @@ -915,14 +933,14 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages() else if (DSPGenerationStart::match(*message)) { if (m_stateTx == StReady) { - m_stateTx = gotoRunning(1); + setStateTx(gotoRunning(1)); } returnState = m_stateTx; } else if (DSPGenerationStop::match(*message)) { - m_stateTx = gotoIdle(1); + setStateTx(gotoIdle(1)); returnState = m_stateTx; } else if (GetMIMODeviceDescription::match(*message)) diff --git a/sdrbase/dsp/dspdevicemimoengine.h b/sdrbase/dsp/dspdevicemimoengine.h index dfc102281..d076b0440 100644 --- a/sdrbase/dsp/dspdevicemimoengine.h +++ b/sdrbase/dsp/dspdevicemimoengine.h @@ -350,6 +350,8 @@ private: State gotoInit(int subsystemIndex); //!< Go to the acquisition init state from idle State gotoRunning(int subsystemIndex); //!< Go to the running state from ready state State gotoError(int subsystemIndex, const QString& errorMsg); //!< Go to an error state + void setStateRx(State state); + void setStateTx(State state); void handleSetMIMO(DeviceSampleMIMO* mimo); //!< Manage MIMO device setting void iqCorrections(SampleVector::iterator begin, SampleVector::iterator end, int isource, bool imbalanceCorrection); @@ -361,6 +363,9 @@ private slots: void handleDataTxAsync(int streamIndex); //!< Handle data when Tx samples have to be processed asynchronously void handleSynchronousMessages(); //!< Handle synchronous messages with the thread void handleInputMessages(); //!< Handle input message queue + +signals: + void stateChanged(); }; #endif // SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_ diff --git a/sdrbase/dsp/dspdevicesinkengine.cpp b/sdrbase/dsp/dspdevicesinkengine.cpp index add22cdbb..2282adb60 100644 --- a/sdrbase/dsp/dspdevicesinkengine.cpp +++ b/sdrbase/dsp/dspdevicesinkengine.cpp @@ -50,10 +50,19 @@ DSPDeviceSinkEngine::~DSPDeviceSinkEngine() wait(); } +void DSPDeviceSinkEngine::setState(State state) +{ + if (m_state != state) + { + m_state = state; + emit stateChanged(); + } +} + void DSPDeviceSinkEngine::run() { qDebug() << "DSPDeviceSinkEngine::run"; - m_state = StIdle; + setState(StIdle); exec(); } @@ -67,7 +76,7 @@ void DSPDeviceSinkEngine::stop() { qDebug() << "DSPDeviceSinkEngine::stop"; gotoIdle(); - m_state = StNotStarted; + setState(StNotStarted); QThread::exit(); // DSPExit cmd; // m_syncMessenger.sendWait(cmd); @@ -388,7 +397,7 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoError(const QString& errorMe m_errorMessage = errorMessage; m_deviceDescription.clear(); - m_state = StError; + setState(StError); return StError; } @@ -426,21 +435,21 @@ void DSPDeviceSinkEngine::handleSynchronousMessages() if (DSPGenerationInit::match(*message)) { - m_state = gotoIdle(); + setState(gotoIdle()); if(m_state == StIdle) { - m_state = gotoInit(); // State goes ready if init is performed + setState(gotoInit()); // State goes ready if init is performed } } else if (DSPGenerationStart::match(*message)) { if(m_state == StReady) { - m_state = gotoRunning(); + setState(gotoRunning()); } } else if (DSPGenerationStop::match(*message)) { - m_state = gotoIdle(); + setState(gotoIdle()); } else if (DSPGetSinkDeviceDescription::match(*message)) { diff --git a/sdrbase/dsp/dspdevicesinkengine.h b/sdrbase/dsp/dspdevicesinkengine.h index 05ec4d32b..a26a39558 100644 --- a/sdrbase/dsp/dspdevicesinkengine.h +++ b/sdrbase/dsp/dspdevicesinkengine.h @@ -113,6 +113,7 @@ private: State gotoInit(); //!< Go to the acquisition init state from idle State gotoRunning(); //!< Go to the running state from ready state State gotoError(const QString& errorMsg); //!< Go to an error state + void setState(State state); void handleSetSink(DeviceSampleSink* sink); //!< Manage sink setting @@ -120,6 +121,9 @@ private slots: void handleData(); //!< Handle data when samples have to be written to the sample FIFO void handleInputMessages(); //!< Handle input message queue void handleSynchronousMessages(); //!< Handle synchronous messages with the thread + +signals: + void stateChanged(); }; diff --git a/sdrbase/dsp/dspdevicesourceengine.cpp b/sdrbase/dsp/dspdevicesourceengine.cpp index 4d431c9f1..19de9b845 100644 --- a/sdrbase/dsp/dspdevicesourceengine.cpp +++ b/sdrbase/dsp/dspdevicesourceengine.cpp @@ -55,10 +55,19 @@ DSPDeviceSourceEngine::~DSPDeviceSourceEngine() wait(); } +void DSPDeviceSourceEngine::setState(State state) +{ + if (m_state != state) + { + m_state = state; + emit stateChanged(); + } +} + void DSPDeviceSourceEngine::run() { qDebug() << "DSPDeviceSourceEngine::run"; - m_state = StIdle; + setState(StIdle); exec(); } @@ -72,7 +81,7 @@ void DSPDeviceSourceEngine::stop() { qDebug() << "DSPDeviceSourceEngine::stop"; gotoIdle(); - m_state = StNotStarted; + setState(StNotStarted); QThread::exit(); // DSPExit cmd; // m_syncMessenger.sendWait(cmd); @@ -508,7 +517,7 @@ DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoError(const QString& err m_errorMessage = errorMessage; m_deviceDescription.clear(); - m_state = StError; + setState(StError); return StError; } @@ -549,21 +558,21 @@ void DSPDeviceSourceEngine::handleSynchronousMessages() if (DSPAcquisitionInit::match(*message)) { - m_state = gotoIdle(); + setState(gotoIdle()); if(m_state == StIdle) { - m_state = gotoInit(); // State goes ready if init is performed + setState(gotoInit()); // State goes ready if init is performed } } else if (DSPAcquisitionStart::match(*message)) { if(m_state == StReady) { - m_state = gotoRunning(); + setState(gotoRunning()); } } else if (DSPAcquisitionStop::match(*message)) { - m_state = gotoIdle(); + setState(gotoIdle()); } else if (DSPGetSourceDeviceDescription::match(*message)) { diff --git a/sdrbase/dsp/dspdevicesourceengine.h b/sdrbase/dsp/dspdevicesourceengine.h index 83a92c582..1b4fab35b 100644 --- a/sdrbase/dsp/dspdevicesourceengine.h +++ b/sdrbase/dsp/dspdevicesourceengine.h @@ -134,6 +134,7 @@ private: State gotoInit(); //!< Go to the acquisition init state from idle State gotoRunning(); //!< Go to the running state from ready state State gotoError(const QString& errorMsg); //!< Go to an error state + void setState(State state); void handleSetSource(DeviceSampleSource* source); //!< Manage source setting @@ -141,6 +142,9 @@ private slots: void handleData(); //!< Handle data when samples from source FIFO are ready to be processed void handleInputMessages(); //!< Handle input message queue void handleSynchronousMessages(); //!< Handle synchronous messages with the thread + +signals: + void stateChanged(); }; #endif // INCLUDE_DSPDEVICEENGINE_H diff --git a/sdrbase/maincore.h b/sdrbase/maincore.h index b4d77e8a4..dcf44ddef 100644 --- a/sdrbase/maincore.h +++ b/sdrbase/maincore.h @@ -886,6 +886,7 @@ public: signals: void deviceSetAdded(int index, DeviceAPI *device); void deviceChanged(int index); + void deviceStateChanged(int index, DeviceAPI *device); void deviceSetRemoved(int index); void channelAdded(int deviceSetIndex, ChannelAPI *channel); void channelRemoved(int deviceSetIndex, ChannelAPI *oldChannel); diff --git a/sdrgui/gui/workspace.cpp b/sdrgui/gui/workspace.cpp index ab2b5ece8..3ae06afe9 100644 --- a/sdrgui/gui/workspace.cpp +++ b/sdrgui/gui/workspace.cpp @@ -34,8 +34,10 @@ #include "channel/channelgui.h" #include "feature/featuregui.h" #include "device/devicegui.h" +#include "device/deviceset.h" #include "mainspectrum/mainspectrumgui.h" #include "workspace.h" +#include "maincore.h" Workspace::Workspace(int index, QWidget *parent, Qt::WindowFlags flags) : QDockWidget(parent, flags), @@ -80,6 +82,11 @@ Workspace::Workspace(int index, QWidget *parent, Qt::WindowFlags flags) : m_addMIMODeviceButton->setToolTip("Add MIMO device"); m_addMIMODeviceButton->setFixedSize(20, 20); + m_startStopButton = new ButtonSwitch(); + m_startStopButton->setCheckable(true); + updateStartStopButton(false); + m_startStopButton->setFixedSize(20, 20); + m_vline1 = new QFrame(); m_vline1->setFrameShape(QFrame::VLine); m_vline1->setFrameShadow(QFrame::Sunken); @@ -142,6 +149,7 @@ Workspace::Workspace(int index, QWidget *parent, Qt::WindowFlags flags) : m_titleBarLayout->addWidget(m_addRxDeviceButton); m_titleBarLayout->addWidget(m_addTxDeviceButton); m_titleBarLayout->addWidget(m_addMIMODeviceButton); + m_titleBarLayout->addWidget(m_startStopButton); m_titleBarLayout->addWidget(m_vline1); m_titleBarLayout->addWidget(m_addFeatureButton); m_titleBarLayout->addWidget(m_featurePresetsButton); @@ -211,6 +219,13 @@ Workspace::Workspace(int index, QWidget *parent, Qt::WindowFlags flags) : &Workspace::stackSubWindows ); + QObject::connect( + m_startStopButton, + &ButtonSwitch::clicked, + this, + &Workspace::startStopClicked + ); + QObject::connect( m_autoStackSubWindows, &QPushButton::clicked, @@ -234,6 +249,13 @@ Workspace::Workspace(int index, QWidget *parent, Qt::WindowFlags flags) : &Workspace::addFeatureEmitted ); + QObject::connect( + MainCore::instance(), + &MainCore::deviceStateChanged, + this, + &Workspace::deviceStateChanged + ); + } Workspace::~Workspace() @@ -247,6 +269,7 @@ Workspace::~Workspace() delete m_cascadeSubWindows; delete m_vline2; delete m_vline1; + delete m_startStopButton; delete m_addRxDeviceButton; delete m_addTxDeviceButton; delete m_addMIMODeviceButton; @@ -598,12 +621,66 @@ void Workspace::stackSubWindows() void Workspace::autoStackSubWindows() { - // FIXME: Need to save whether this is checked as a preference if (m_autoStackSubWindows->isChecked()) { stackSubWindows(); } } +// Start/stop all devices in workspace +void Workspace::startStopClicked(bool checked) +{ + if (!checked) { + emit stopAllDevices(this); + } else { + emit startAllDevices(this); + } + updateStartStopButton(checked); +} + +void Workspace::updateStartStopButton(bool checked) +{ + if (!checked) + { + QIcon startIcon(":/play.png"); + m_startStopButton->setIcon(startIcon); + m_startStopButton->setStyleSheet("QToolButton { background-color : blue; }"); + m_startStopButton->setToolTip("Start all devices in workspace"); + } + else + { + QIcon stopIcon(":/stop.png"); + m_startStopButton->setIcon(stopIcon); + m_startStopButton->setStyleSheet("QToolButton { background-color : green; }"); + m_startStopButton->setToolTip("Stop all devices in workspace"); + } +} + +void Workspace::deviceStateChanged(int index, DeviceAPI *deviceAPI) +{ + if (deviceAPI->getWorkspaceIndex() == m_index) + { + // Check state of all devices in workspace, to see if any are running or have errors + bool running = false; + bool error = false; + std::vector deviceSets = MainCore::instance()->getDeviceSets(); + for (auto deviceSet : deviceSets) + { + DeviceAPI::EngineState state = deviceSet->m_deviceAPI->state(); + if (state == DeviceAPI::StRunning) { + running = true; + } else if (state == DeviceAPI::StError) { + error = true; + } + } + // Update start/stop button to reflect current state of devices + updateStartStopButton(running); + m_startStopButton->setChecked(running); + if (error) { + m_startStopButton->setStyleSheet("QToolButton { background-color : red; }"); + } + } +} + void Workspace::resizeEvent(QResizeEvent *event) { QDockWidget::resizeEvent(event); diff --git a/sdrgui/gui/workspace.h b/sdrgui/gui/workspace.h index 8b0a3249d..a79eeff03 100644 --- a/sdrgui/gui/workspace.h +++ b/sdrgui/gui/workspace.h @@ -23,6 +23,7 @@ #include "export.h" #include "featureadddialog.h" +#include "device/deviceapi.h" class QHBoxLayout; class QLabel; @@ -61,12 +62,14 @@ public: void orderByIndex(QList &list); void orderByIndex(QList &list); void adjustSubWindowsAfterRestore(); + void updateStartStopButton(bool checked); private: int m_index; QPushButton *m_addRxDeviceButton; QPushButton *m_addTxDeviceButton; QPushButton *m_addMIMODeviceButton; + ButtonSwitch *m_startStopButton; QFrame *m_vline1; QPushButton *m_addFeatureButton; QPushButton *m_featurePresetsButton; @@ -99,8 +102,10 @@ private slots: void tileSubWindows(); void stackSubWindows(); void autoStackSubWindows(); + void startStopClicked(bool checked = false); void addFeatureEmitted(int featureIndex); void toggleFloating(); + void deviceStateChanged(int index, DeviceAPI *deviceAPI); signals: void addRxDevice(Workspace *inWorkspace, int deviceIndex); @@ -108,6 +113,8 @@ signals: void addMIMODevice(Workspace *inWorkspace, int deviceIndex); void addFeature(Workspace*, int); void featurePresetsDialogRequested(QPoint, Workspace*); + void startAllDevices(Workspace *inWorkspace); + void stopAllDevices(Workspace *inWorkspace); }; diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index c2e69fe2c..f87e201c5 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -43,6 +43,7 @@ #include "device/deviceenumerator.h" #include "channel/channelapi.h" #include "channel/channelgui.h" +#include "channel/channelwebapiutils.h" #include "feature/featureuiset.h" #include "feature/featureset.h" #include "feature/feature.h" @@ -326,6 +327,13 @@ void MainWindow::sampleSourceAdd(Workspace *deviceWorkspace, Workspace *spectrum &MainWindow::mainSpectrumRequestDeviceCenterFrequency ); + QObject::connect( + deviceAPI, + &DeviceAPI::stateChanged, + this, + &MainWindow::deviceStateChanged + ); + deviceWorkspace->addToMdiArea(m_deviceUIs.back()->m_deviceGUI); spectrumWorkspace->addToMdiArea(m_deviceUIs.back()->m_mainSpectrumGUI); emit m_mainCore->deviceSetAdded(deviceSetIndex, deviceAPI); @@ -549,6 +557,13 @@ void MainWindow::sampleSinkAdd(Workspace *deviceWorkspace, Workspace *spectrumWo &MainWindow::mainSpectrumRequestDeviceCenterFrequency ); + QObject::connect( + deviceAPI, + &DeviceAPI::stateChanged, + this, + &MainWindow::deviceStateChanged + ); + deviceWorkspace->addToMdiArea(m_deviceUIs.back()->m_deviceGUI); spectrumWorkspace->addToMdiArea(m_deviceUIs.back()->m_mainSpectrumGUI); emit m_mainCore->deviceSetAdded(deviceSetIndex, deviceAPI); @@ -773,6 +788,13 @@ void MainWindow::sampleMIMOAdd(Workspace *deviceWorkspace, Workspace *spectrumWo [=](int channelPluginIndex){ this->channelAddClicked(deviceWorkspace, deviceSetIndex, channelPluginIndex); } ); + QObject::connect( + deviceAPI, + &DeviceAPI::stateChanged, + this, + &MainWindow::deviceStateChanged + ); + deviceWorkspace->addToMdiArea(m_deviceUIs.back()->m_deviceGUI); spectrumWorkspace->addToMdiArea(m_deviceUIs.back()->m_mainSpectrumGUI); emit m_mainCore->deviceSetAdded(deviceSetIndex, deviceAPI); @@ -1897,6 +1919,20 @@ void MainWindow::addWorkspace() &MainWindow::openFeaturePresetsDialog ); + QObject::connect( + m_workspaces.back(), + &Workspace::startAllDevices, + this, + &MainWindow::startAllDevices + ); + + QObject::connect( + m_workspaces.back(), + &Workspace::stopAllDevices, + this, + &MainWindow::stopAllDevices + ); + if (m_workspaces.size() > 1) { for (int i = 1; i < m_workspaces.size(); i++) { @@ -2704,6 +2740,41 @@ void MainWindow::showAllChannels(int deviceSetIndex) } } +// Start all devices in the workspace +void MainWindow::startAllDevices(Workspace *workspace) +{ + int workspaceIndex = workspace->getIndex(); + for (auto deviceUI : m_deviceUIs) + { + if (deviceUI->m_deviceAPI->getWorkspaceIndex() == workspaceIndex) + { + // We use WebAPI rather than call deviceUI->m_deviceAPI->startDeviceEngine(); + // so that the start/stop button in the Device GUI is correctly updated + int deviceIndex = deviceUI->m_deviceAPI->getDeviceSetIndex(); + ChannelWebAPIUtils::run(deviceIndex); + } + } +} + +// Stop all devices in the workspace +void MainWindow::stopAllDevices(Workspace *workspace) +{ + int workspaceIndex = workspace->getIndex(); + for (auto deviceUI : m_deviceUIs) + { + if (deviceUI->m_deviceAPI->getWorkspaceIndex() == workspaceIndex) + { + int deviceIndex = deviceUI->m_deviceAPI->getDeviceSetIndex(); + ChannelWebAPIUtils::stop(deviceIndex); + } + } +} + +void MainWindow::deviceStateChanged(DeviceAPI *deviceAPI) +{ + emit m_mainCore->deviceStateChanged(deviceAPI->getDeviceSetIndex(), deviceAPI); +} + void MainWindow::openFeaturePresetsDialog(QPoint p, Workspace *workspace) { FeaturePresetsDialog dialog; diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index 3361e048b..102a5e861 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -203,7 +203,10 @@ private slots: void channelAddClicked(Workspace *workspace, int deviceSetIndex, int channelPluginIndex); void featureAddClicked(Workspace *workspace, int featureIndex); void featureMove(FeatureGUI *gui, int wsIndexDestnation); + void deviceStateChanged(DeviceAPI *deviceAPI); void openFeaturePresetsDialog(QPoint p, Workspace *workspace); + void startAllDevices(Workspace *workspace); + void stopAllDevices(Workspace *workspace); void deviceMove(DeviceGUI *gui, int wsIndexDestnation); void mainSpectrumMove(MainSpectrumGUI *gui, int wsIndexDestnation); void mainSpectrumShow(int deviceSetIndex);