From 5af1e12f6d4c86d2d302fed9ce66d398ec508454 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 13 Sep 2020 17:50:24 +0200 Subject: [PATCH] New sampling devices dock with change and reload buttons. Implements #629 --- sdrgui/CMakeLists.txt | 2 + sdrgui/gui/channelsdock.cpp | 1 + sdrgui/gui/samplingdevicecontrol.cpp | 1 - sdrgui/gui/samplingdevicecontrol.h | 2 - sdrgui/gui/samplingdevicedialog.cpp | 34 +++- sdrgui/gui/samplingdevicedialog.h | 10 +- sdrgui/gui/samplingdevicesdock.cpp | 183 +++++++++++++++++++++ sdrgui/gui/samplingdevicesdock.h | 81 +++++++++ sdrgui/mainwindow.cpp | 237 ++++++++++++++++++++++++++- sdrgui/mainwindow.h | 3 + sdrgui/mainwindow.ui | 100 +++++------ sdrgui/resources/res.qrc | 1 + sdrgui/resources/swap.png | Bin 0 -> 1433 bytes 13 files changed, 601 insertions(+), 54 deletions(-) create mode 100644 sdrgui/gui/samplingdevicesdock.cpp create mode 100644 sdrgui/gui/samplingdevicesdock.h create mode 100644 sdrgui/resources/swap.png diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index d5a6324aa..5c88d2ea9 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -47,6 +47,7 @@ set(sdrgui_SOURCES gui/rollupwidget.cpp gui/samplingdevicecontrol.cpp gui/samplingdevicedialog.cpp + gui/samplingdevicesdock.cpp gui/scaleengine.cpp gui/sdrangelsplash.cpp gui/tickedslider.cpp @@ -122,6 +123,7 @@ set(sdrgui_HEADERS gui/rollupwidget.h gui/samplingdevicecontrol.h gui/samplingdevicedialog.h + gui/samplingdevicesdock.h gui/scaleengine.h gui/sdrangelsplash.h gui/tickedslider.h diff --git a/sdrgui/gui/channelsdock.cpp b/sdrgui/gui/channelsdock.cpp index 9cab1ed3f..f8e1d0ebd 100644 --- a/sdrgui/gui/channelsdock.cpp +++ b/sdrgui/gui/channelsdock.cpp @@ -85,6 +85,7 @@ ChannelsDock::~ChannelsDock() { delete m_closeButton; delete m_normalButton; + delete m_addChannelButton; delete m_titleLabel; delete m_titleBarLayout; delete m_titleBar; diff --git a/sdrgui/gui/samplingdevicecontrol.cpp b/sdrgui/gui/samplingdevicecontrol.cpp index ea716160b..6db786b70 100644 --- a/sdrgui/gui/samplingdevicecontrol.cpp +++ b/sdrgui/gui/samplingdevicecontrol.cpp @@ -25,7 +25,6 @@ SamplingDeviceControl::SamplingDeviceControl(int tabIndex, int deviceType, QWidget* parent) : QWidget(parent), ui(new Ui::SamplingDeviceControl), - m_pluginManager(0), m_deviceTabIndex(tabIndex), m_deviceType(deviceType), m_selectedDeviceIndex(-1) diff --git a/sdrgui/gui/samplingdevicecontrol.h b/sdrgui/gui/samplingdevicecontrol.h index 8b1df2d1d..925d53e2f 100644 --- a/sdrgui/gui/samplingdevicecontrol.h +++ b/sdrgui/gui/samplingdevicecontrol.h @@ -42,7 +42,6 @@ public: int getSelectedDeviceIndex() const { return m_selectedDeviceIndex; } void setSelectedDeviceIndex(int index); void removeSelectedDeviceIndex(); - void setPluginManager(PluginManager *pluginManager) { m_pluginManager = pluginManager; } private slots: void on_deviceChange_clicked(); @@ -50,7 +49,6 @@ private slots: private: Ui::SamplingDeviceControl* ui; - PluginManager *m_pluginManager; int m_deviceTabIndex; int m_deviceType; int m_selectedDeviceIndex; diff --git a/sdrgui/gui/samplingdevicedialog.cpp b/sdrgui/gui/samplingdevicedialog.cpp index 59dddba6b..cf42381b2 100644 --- a/sdrgui/gui/samplingdevicedialog.cpp +++ b/sdrgui/gui/samplingdevicedialog.cpp @@ -29,7 +29,8 @@ SamplingDeviceDialog::SamplingDeviceDialog(int deviceType, int deviceTabIndex, Q ui(new Ui::SamplingDeviceDialog), m_deviceType(deviceType), m_deviceTabIndex(deviceTabIndex), - m_selectedDeviceIndex(-1) + m_selectedDeviceIndex(-1), + m_hasChanged(false) { ui->setupUi(this); @@ -52,6 +53,31 @@ SamplingDeviceDialog::~SamplingDeviceDialog() delete ui; } +int SamplingDeviceDialog::exec() +{ + m_hasChanged = false; + return QDialog::exec(); +} + +void SamplingDeviceDialog::setSelectedDeviceIndex(int deviceIndex) +{ + ui->deviceSelect->blockSignals(true); + ui->deviceSelect->setCurrentIndex(deviceIndex); + m_selectedDeviceIndex = deviceIndex; + ui->deviceSelect->blockSignals(false); +} + +void SamplingDeviceDialog::getDeviceId(QString& id) const +{ + id = ui->deviceSelect->currentText(); +} + +void SamplingDeviceDialog::on_deviceSelect_currentIndexChanged(int index) +{ + (void) index; + m_hasChanged = true; +} + void SamplingDeviceDialog::accept() { m_selectedDeviceIndex = m_deviceIndexes[ui->deviceSelect->currentIndex()]; @@ -66,3 +92,9 @@ void SamplingDeviceDialog::accept() QDialog::accept(); } + +void SamplingDeviceDialog::reject() +{ + m_hasChanged = false; + QDialog::reject(); +} diff --git a/sdrgui/gui/samplingdevicedialog.h b/sdrgui/gui/samplingdevicedialog.h index 9b05f9876..9a5a3dc9c 100644 --- a/sdrgui/gui/samplingdevicedialog.h +++ b/sdrgui/gui/samplingdevicedialog.h @@ -35,9 +35,14 @@ class SDRGUI_API SamplingDeviceDialog : public QDialog { Q_OBJECT public: - explicit SamplingDeviceDialog(int deviceType, int deviceTabIndex, QWidget* parent = 0); + explicit SamplingDeviceDialog(int deviceType, int deviceTabIndex, QWidget* parent = nullptr); ~SamplingDeviceDialog(); int getSelectedDeviceIndex() const { return m_selectedDeviceIndex; } + void setSelectedDeviceIndex(int deviceIndex); + void setTabIndex(int deviceTabIndex) { m_deviceTabIndex = deviceTabIndex; } + void getDeviceId(QString& id) const; + int exec(); + bool hasChanged() const { return m_hasChanged; } private: Ui::SamplingDeviceDialog* ui; @@ -45,9 +50,12 @@ private: int m_deviceTabIndex; int m_selectedDeviceIndex; std::vector m_deviceIndexes; + bool m_hasChanged; private slots: + void on_deviceSelect_currentIndexChanged(int index); void accept(); + void reject(); }; #endif /* SDRGUI_GUI_SAMPLINGDEVICEDIALOG_H_ */ diff --git a/sdrgui/gui/samplingdevicesdock.cpp b/sdrgui/gui/samplingdevicesdock.cpp new file mode 100644 index 000000000..95f49b7eb --- /dev/null +++ b/sdrgui/gui/samplingdevicesdock.cpp @@ -0,0 +1,183 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 F4EXB // +// written by Edouard Griffiths // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#include "device/deviceenumerator.h" +#include "samplingdevicesdock.h" + +SamplingDevicesDock::SamplingDevicesDock(QWidget *parent, Qt::WindowFlags flags) : + QDockWidget(parent, flags), + m_currentTabIndex(0) +{ + m_titleBar = new QWidget(); + m_titleBarLayout = new QHBoxLayout(); + m_titleBarLayout->setMargin(1); + m_titleBar->setLayout(m_titleBarLayout); + + m_titleLabel = new QLabel(); + m_titleLabel->setText(QString("Sampling device")); // will be changed dynamically + + m_changeDeviceButton = new QPushButton(); + QIcon changeIcon(":/swap.png"); + m_changeDeviceButton->setIcon(changeIcon); + m_changeDeviceButton->setToolTip("Change device"); + m_changeDeviceButton->setFixedSize(16, 16); + + m_reloadDeviceButton = new QPushButton(); + QIcon reloadIcon(":/recycle.png"); + m_reloadDeviceButton->setIcon(reloadIcon); + m_reloadDeviceButton->setToolTip("Reload device"); + m_reloadDeviceButton->setFixedSize(16, 16); + + m_normalButton = new QPushButton(); + QIcon normalIcon = style()->standardIcon(QStyle::SP_TitleBarNormalButton, 0, this); + m_normalButton->setIcon(normalIcon); + m_normalButton->setFixedSize(12, 12); + + m_closeButton = new QPushButton(); + QIcon closeIcon = style()->standardIcon(QStyle::SP_TitleBarCloseButton, 0, this); + m_closeButton->setIcon(closeIcon); + m_closeButton->setFixedSize(12, 12); + + m_titleBarLayout->addWidget(m_changeDeviceButton); + m_titleBarLayout->addWidget(m_reloadDeviceButton); + m_titleBarLayout->addWidget(m_titleLabel); + m_titleBarLayout->addWidget(m_normalButton); + m_titleBarLayout->addWidget(m_closeButton); + setTitleBarWidget(m_titleBar); + + QObject::connect( + m_changeDeviceButton, + &QPushButton::clicked, + this, + &SamplingDevicesDock::openChangeDeviceDialog + ); + + QObject::connect( + m_reloadDeviceButton, + &QPushButton::clicked, + this, + &SamplingDevicesDock::reloadDevice + ); + + QObject::connect( + m_normalButton, + &QPushButton::clicked, + this, + &SamplingDevicesDock::toggleFloating + ); + + connect(m_closeButton, SIGNAL(clicked()), this, SLOT(hide())); +} + +SamplingDevicesDock::~SamplingDevicesDock() +{ + for (int i = 0; i < m_devicesInfo.size(); i++) { + delete m_devicesInfo[i].m_samplingDeviceDialog; + } + + delete m_closeButton; + delete m_normalButton; + delete m_reloadDeviceButton; + delete m_changeDeviceButton; + delete m_titleLabel; + delete m_titleBarLayout; + delete m_titleBar; +} + +void SamplingDevicesDock::addDevice(int deviceType, int deviceTabIndex) +{ + m_devicesInfo.push_back(DeviceInfo{ + deviceType, + deviceTabIndex, + new SamplingDeviceDialog(deviceType, deviceTabIndex, this) + }); + + setCurrentTabIndex(deviceTabIndex); +} + +void SamplingDevicesDock::removeLastDevice() +{ + if (m_devicesInfo.size() > 0) + { + delete m_devicesInfo.back().m_samplingDeviceDialog; + m_devicesInfo.pop_back(); + } +} + +void SamplingDevicesDock::setCurrentTabIndex(int deviceTabIndex) +{ + m_currentTabIndex = deviceTabIndex; + QString newTitle; + m_devicesInfo[m_currentTabIndex].m_samplingDeviceDialog->getDeviceId(newTitle); + int newTitleSize = newTitle.size(); + + if (newTitleSize > 0) + { + if (newTitleSize > 40) { + newTitle.chop(newTitleSize - 40); + } + + m_titleLabel->setText(newTitle); + } +} + +void SamplingDevicesDock::setSelectedDeviceIndex(int deviceTabIndex, int deviceIndex) +{ + if (deviceTabIndex < m_devicesInfo.size()) + { + m_devicesInfo[deviceTabIndex].m_samplingDeviceDialog->setSelectedDeviceIndex(deviceIndex); + setCurrentTabIndex(m_currentTabIndex); // update title + } +} + +void SamplingDevicesDock::toggleFloating() +{ + setFloating(!isFloating()); +} + +void SamplingDevicesDock::reloadDevice() +{ + emit deviceChanged( + m_devicesInfo[m_currentTabIndex].m_deviceType, + m_devicesInfo[m_currentTabIndex].m_deviceTabIndex, + m_devicesInfo[m_currentTabIndex].m_samplingDeviceDialog->getSelectedDeviceIndex() + ); +} + +void SamplingDevicesDock::openChangeDeviceDialog() +{ + if (m_currentTabIndex < m_devicesInfo.size()) + { + m_devicesInfo[m_currentTabIndex].m_samplingDeviceDialog->exec(); + + if (m_devicesInfo[m_currentTabIndex].m_samplingDeviceDialog->hasChanged()) + { + setCurrentTabIndex(m_currentTabIndex); // update title + emit deviceChanged( + m_devicesInfo[m_currentTabIndex].m_deviceType, + m_devicesInfo[m_currentTabIndex].m_deviceTabIndex, + m_devicesInfo[m_currentTabIndex].m_samplingDeviceDialog->getSelectedDeviceIndex() + ); + } + } +} diff --git a/sdrgui/gui/samplingdevicesdock.h b/sdrgui/gui/samplingdevicesdock.h new file mode 100644 index 000000000..a1eb75ca5 --- /dev/null +++ b/sdrgui/gui/samplingdevicesdock.h @@ -0,0 +1,81 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 F4EXB // +// written by Edouard Griffiths // +// // +// 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 SDRGUI_GUI_SAMPLINGDEVICESDOCK_H_ +#define SDRGUI_GUI_SAMPLINGDEVICESDOCK_H_ + +#include +#include + +#include "samplingdevicedialog.h" + +class QHBoxLayout; +class QLabel; +class QPushButton; +class SamplingDeviceDialog; + +class SamplingDevicesDock : public QDockWidget +{ + Q_OBJECT +public: + SamplingDevicesDock(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); + ~SamplingDevicesDock(); + + void addDevice(int deviceType, int deviceTabIndex); + void removeLastDevice(); + void setCurrentTabIndex(int deviceTabIndex); + void setSelectedDeviceIndex(int deviceTabIndex, int deviceIndex); + +private: + struct DeviceInfo + { + DeviceInfo(int deviceType, int deviceTabIndex, SamplingDeviceDialog *samplingDeviceDialog) : + m_deviceType(deviceType), + m_deviceTabIndex(deviceTabIndex), + m_samplingDeviceDialog(samplingDeviceDialog) + {} + DeviceInfo(const DeviceInfo& other) : + m_deviceType(other.m_deviceType), + m_deviceTabIndex(other.m_deviceTabIndex), + m_samplingDeviceDialog(other.m_samplingDeviceDialog) + {} + int m_deviceType; + int m_deviceTabIndex; + SamplingDeviceDialog *m_samplingDeviceDialog; + }; + + QPushButton *m_changeDeviceButton; + QPushButton *m_reloadDeviceButton; + QWidget *m_titleBar; + QHBoxLayout *m_titleBarLayout; + QLabel *m_titleLabel; + QPushButton *m_normalButton; + QPushButton *m_closeButton; + QList m_devicesInfo; + int m_currentTabIndex; + +private slots: + void toggleFloating(); + void reloadDevice(); + void openChangeDeviceDialog(); + +signals: + void deviceChanged(int deviceType, int deviceTabIndex, int newDeviceIndex); +}; + +#endif // SDRGUI_GUI_SAMPLINGDEVICESDOCK_H_ \ No newline at end of file diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index ed672d427..e362f573a 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -227,6 +227,7 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse connect(ui->tabInputsView, SIGNAL(currentChanged(int)), this, SLOT(tabInputViewIndexChanged())); connect(ui->tabChannels, SIGNAL(currentChanged(int)), this, SLOT(tabChannelsIndexChanged())); connect(ui->channelDock, SIGNAL(addChannel(int)), this, SLOT(channelAddClicked(int))); + connect(ui->inputViewDock, SIGNAL(deviceChanged(int, int, int)), this, SLOT(samplingDeviceChanged(int, int, int))); QString applicationDirPath = qApp->applicationDirPath(); @@ -303,6 +304,8 @@ void MainWindow::addSourceDevice(int deviceIndex) sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID); int deviceTabIndex = m_deviceUIs.size(); + ui->inputViewDock->addDevice(0, deviceTabIndex); + m_deviceUIs.push_back(new DeviceUISet(deviceTabIndex, 0, m_masterTimer)); m_deviceUIs.back()->m_deviceSourceEngine = dspDeviceSourceEngine; m_deviceUIs.back()->m_deviceSinkEngine = nullptr; @@ -314,7 +317,6 @@ void MainWindow::addSourceDevice(int deviceIndex) DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleRx, deviceTabIndex, dspDeviceSourceEngine, nullptr, nullptr); m_deviceUIs.back()->m_deviceAPI = deviceAPI; - m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager); QList channelNames; m_pluginManager->listRxChannels(channelNames); m_deviceUIs.back()->setNumberOfAvailableRxChannels(channelNames.size()); @@ -351,6 +353,7 @@ void MainWindow::addSourceDevice(int deviceIndex) } m_deviceUIs.back()->m_samplingDeviceControl->setSelectedDeviceIndex(deviceIndex); + ui->inputViewDock->setSelectedDeviceIndex(deviceTabIndex, deviceIndex); // delete previous plugin GUI m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI( @@ -381,6 +384,8 @@ void MainWindow::addSinkDevice() sprintf(uidCStr, "UID:%d", dspDeviceSinkEngineUID); int deviceTabIndex = m_deviceUIs.size(); + ui->inputViewDock->addDevice(1, deviceTabIndex); + m_deviceUIs.push_back(new DeviceUISet(deviceTabIndex, 1, m_masterTimer)); m_deviceUIs.back()->m_deviceSourceEngine = nullptr; m_deviceUIs.back()->m_deviceSinkEngine = dspDeviceSinkEngine; @@ -392,7 +397,6 @@ void MainWindow::addSinkDevice() DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleTx, deviceTabIndex, nullptr, dspDeviceSinkEngine, nullptr); m_deviceUIs.back()->m_deviceAPI = deviceAPI; - m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager); QList channelNames; m_pluginManager->listTxChannels(channelNames); m_deviceUIs.back()->setNumberOfAvailableTxChannels(channelNames.size()); @@ -427,6 +431,7 @@ void MainWindow::addSinkDevice() } m_deviceUIs.back()->m_samplingDeviceControl->setSelectedDeviceIndex(fileSinkDeviceIndex); + ui->inputViewDock->setSelectedDeviceIndex(deviceTabIndex, fileSinkDeviceIndex); // delete previous plugin GUI if it exists m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI( @@ -959,6 +964,7 @@ bool MainWindow::handleMessage(const Message& cmd) ui->tabInputsSelect->setCurrentIndex(notif.getDeviceSetIndex()); DeviceUISet *deviceUI = m_deviceUIs[notif.getDeviceSetIndex()]; deviceUI->m_samplingDeviceControl->setSelectedDeviceIndex(notif.getDeviceIndex()); + ui->inputViewDock->setSelectedDeviceIndex(notif.getDeviceSetIndex(), notif.getDeviceIndex()); if (notif.getDeviceType() == 1) { sampleSinkChanged(); @@ -1625,6 +1631,128 @@ void MainWindow::on_action_LimeRFE_triggered() #endif } +void MainWindow::samplingDeviceChanged(int deviceType, int tabIndex, int newDeviceIndex) +{ + qDebug("MainWindow::samplingDeviceChanged: deviceType: %d tabIndex: %d newDeviceIndex: %d", + deviceType, tabIndex, newDeviceIndex); + const PluginInterface::SamplingDevice *samplingDevice; + + if (deviceType == 0) { + sampleSourceChanged(tabIndex, newDeviceIndex); + } else if (deviceType == 1) { + sampleSinkChanged(tabIndex, newDeviceIndex); + } +} + +void MainWindow::sampleSourceChanged(int tabIndex, int newDeviceIndex) +{ + if (tabIndex >= 0) + { + qDebug("MainWindow::sampleSourceChanged: tab at %d", tabIndex); + DeviceUISet *deviceUI = m_deviceUIs[tabIndex]; + deviceUI->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings + deviceUI->m_deviceAPI->stopDeviceEngine(); + + // deletes old UI and input object + deviceUI->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(nullptr); // have source stop sending messages to the GUI + deviceUI->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI( + deviceUI->m_deviceAPI->getSamplingDevicePluginInstanceGUI()); + deviceUI->m_deviceAPI->resetSamplingDeviceId(); + deviceUI->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput( + deviceUI->m_deviceAPI->getSampleSource()); + deviceUI->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists + + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(newDeviceIndex); + qDebug("MainWindow::sampleSourceChanged: %s", qPrintable(samplingDevice->hardwareId)); + + deviceUI->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + deviceUI->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + deviceUI->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + deviceUI->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + deviceUI->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getRxPluginInterface(newDeviceIndex)); + + if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default + { + qDebug("MainWindow::sampleSourceChanged: non existent device replaced by File Input"); + int fileInputDeviceIndex = DeviceEnumerator::instance()->getFileInputDeviceIndex(); + samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(fileInputDeviceIndex); + deviceUI->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + deviceUI->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + deviceUI->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + deviceUI->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + deviceUI->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getRxPluginInterface(fileInputDeviceIndex)); + } + + QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence); + + if (userArgs.size() > 0) { + deviceUI->m_deviceAPI->setHardwareUserArguments(userArgs); + } + + // add to buddies list + std::vector::iterator it = m_deviceUIs.begin(); + int nbOfBuddies = 0; + + for (; it != m_deviceUIs.end(); ++it) + { + if (*it != deviceUI) // do not add to itself + { + if ((*it)->m_deviceSourceEngine) // it is a source device + { + if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSourceBuddy(deviceUI->m_deviceAPI); + nbOfBuddies++; + } + } + + if ((*it)->m_deviceSinkEngine) // it is a sink device + { + if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSourceBuddy(deviceUI->m_deviceAPI); + nbOfBuddies++; + } + } + } + } + + if (nbOfBuddies == 0) { + deviceUI->m_deviceAPI->setBuddyLeader(true); + } + + // constructs new GUI and input object + DeviceSampleSource *source = deviceUI->m_deviceAPI->getPluginInterface()->createSampleSourcePluginInstance( + deviceUI->m_deviceAPI->getSamplingDeviceId(), deviceUI->m_deviceAPI); + deviceUI->m_deviceAPI->setSampleSource(source); + QWidget *gui; + PluginInstanceGUI *pluginUI = deviceUI->m_deviceAPI->getPluginInterface()->createSampleSourcePluginInstanceGUI( + deviceUI->m_deviceAPI->getSamplingDeviceId(), + &gui, + deviceUI); + deviceUI->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(pluginUI->getInputMessageQueue()); + deviceUI->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginUI); + setDeviceGUI(tabIndex, gui, deviceUI->m_deviceAPI->getSamplingDeviceDisplayName()); + deviceUI->m_deviceAPI->getSampleSource()->init(); + + deviceUI->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings + + if (tabIndex == 0) // save as default starting device + { + m_settings.setSourceIndex(samplingDevice->sequence); + m_settings.setSourceDeviceId(samplingDevice->id); + } + } +} + void MainWindow::sampleSourceChanged() { // Do it in the currently selected source tab @@ -1736,6 +1864,107 @@ void MainWindow::sampleSourceChanged() } } +void MainWindow::sampleSinkChanged(int tabIndex, int newDeviceIndex) +{ + if (tabIndex >= 0) + { + qDebug("MainWindow::sampleSinkChanged: tab at %d", tabIndex); + DeviceUISet *deviceUI = m_deviceUIs[tabIndex]; + deviceUI->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings + deviceUI->m_deviceAPI->stopDeviceEngine(); + + // deletes old UI and output object + deviceUI->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(0); // have sink stop sending messages to the GUI + deviceUI->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI( + deviceUI->m_deviceAPI->getSamplingDevicePluginInstanceGUI()); + deviceUI->m_deviceAPI->resetSamplingDeviceId(); + deviceUI->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( + deviceUI->m_deviceAPI->getSampleSink()); + deviceUI->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists + + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(newDeviceIndex); + deviceUI->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + deviceUI->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + deviceUI->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + deviceUI->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + deviceUI->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getTxPluginInterface(newDeviceIndex)); + + if (deviceUI->m_deviceAPI->getSamplingDeviceId().size() == 0) // non existent device => replace by default + { + qDebug("MainWindow::sampleSinkChanged: non existent device replaced by File Sink"); + int fileSinkDeviceIndex = DeviceEnumerator::instance()->getFileOutputDeviceIndex(); + const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(fileSinkDeviceIndex); + deviceUI->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence); + deviceUI->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems); + deviceUI->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex); + deviceUI->m_deviceAPI->setHardwareId(samplingDevice->hardwareId); + deviceUI->m_deviceAPI->setSamplingDeviceId(samplingDevice->id); + deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial); + deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName); + deviceUI->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getTxPluginInterface(fileSinkDeviceIndex)); + } + + QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence); + + if (userArgs.size() > 0) { + deviceUI->m_deviceAPI->setHardwareUserArguments(userArgs); + } + + // add to buddies list + std::vector::iterator it = m_deviceUIs.begin(); + int nbOfBuddies = 0; + + for (; it != m_deviceUIs.end(); ++it) + { + if (*it != deviceUI) // do not add to itself + { + if ((*it)->m_deviceSourceEngine) // it is a source device + { + if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSinkBuddy(deviceUI->m_deviceAPI); + nbOfBuddies++; + } + } + + if ((*it)->m_deviceSinkEngine) // it is a sink device + { + if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) && + (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial())) + { + (*it)->m_deviceAPI->addSinkBuddy(deviceUI->m_deviceAPI); + nbOfBuddies++; + } + } + } + } + + if (nbOfBuddies == 0) { + deviceUI->m_deviceAPI->setBuddyLeader(true); + } + + // constructs new GUI and output object + DeviceSampleSink *sink = deviceUI->m_deviceAPI->getPluginInterface()->createSampleSinkPluginInstance( + deviceUI->m_deviceAPI->getSamplingDeviceId(), deviceUI->m_deviceAPI); + deviceUI->m_deviceAPI->setSampleSink(sink); + QWidget *gui; + PluginInstanceGUI *pluginUI = deviceUI->m_deviceAPI->getPluginInterface()->createSampleSinkPluginInstanceGUI( + deviceUI->m_deviceAPI->getSamplingDeviceId(), + &gui, + deviceUI); + deviceUI->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(pluginUI->getInputMessageQueue()); + deviceUI->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginUI); + setDeviceGUI(tabIndex, gui, deviceUI->m_deviceAPI->getSamplingDeviceDisplayName(), 1); + deviceUI->m_deviceAPI->getSampleSink()->init(); + + deviceUI->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings + } +} + void MainWindow::sampleSinkChanged() { // Do it in the currently selected source tab @@ -1966,6 +2195,10 @@ void MainWindow::tabInputViewIndexChanged() { int inputViewIndex = ui->tabInputsView->currentIndex(); + if (inputViewIndex >= 0) { + ui->inputViewDock->setCurrentTabIndex(inputViewIndex); + } + if ((inputViewIndex >= 0) && (m_masterTabIndex >= 0) && (inputViewIndex != m_masterTabIndex)) { DeviceUISet *deviceUI = m_deviceUIs[inputViewIndex]; diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index ee7a95db1..3f269d5f4 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -364,6 +364,8 @@ private: void addSinkDevice(); void removeLastDevice(); void deleteChannel(int deviceSetIndex, int channelIndex); + void sampleSourceChanged(int tabIndex, int newDeviceIndex); + void sampleSinkChanged(int tabIndex, int newDeviceIndex); void setLoggingOptions(); @@ -397,6 +399,7 @@ private slots: void on_action_LimeRFE_triggered(); void on_action_My_Position_triggered(); void on_action_DeviceUserArguments_triggered(); + void samplingDeviceChanged(int deviceType, int tabIndex, int newDeviceIndex); void sampleSourceChanged(); void sampleSinkChanged(); void sampleMIMOChanged(); diff --git a/sdrgui/mainwindow.ui b/sdrgui/mainwindow.ui index c91e54440..30945ca9f 100644 --- a/sdrgui/mainwindow.ui +++ b/sdrgui/mainwindow.ui @@ -138,7 +138,7 @@ - + Sampling devices @@ -181,52 +181,6 @@ - - - Sampling devices control - - - 1 - - - - - 0 - 0 - - - - - 3 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - 0 - 110 - - - - -1 - - - - - - Spectrum Display @@ -737,6 +691,52 @@ + + + Sampling devices control + + + 1 + + + + + 0 + 0 + + + + + 3 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + 0 + 110 + + + + -1 + + + + + + E&xit @@ -966,6 +966,12 @@
gui/channelsdock.h
1 + + SamplingDevicesDock + QDockWidget +
gui/samplingdevicesdock.h
+ 1 +
presetTree diff --git a/sdrgui/resources/res.qrc b/sdrgui/resources/res.qrc index b703d3858..eb78d8ede 100644 --- a/sdrgui/resources/res.qrc +++ b/sdrgui/resources/res.qrc @@ -1,5 +1,6 @@ + swap.png gridpolar.png gridrect.png double_arrow_up.png diff --git a/sdrgui/resources/swap.png b/sdrgui/resources/swap.png new file mode 100644 index 0000000000000000000000000000000000000000..cbf3f90dca1abd5e02aae9b30a3b2b80af222a59 GIT binary patch literal 1433 zcmV;K1!nq*P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=KHlH4E+MgLhvmVhLL#Bwm0s_Y=k&jmlGduH;g zrM`$U1_a3H!INBYeR{C38q>o=eUVS1PG+#lYinmDN&At34jBIeONIdxD`7 z^m05}J?$&>`u4)@XM5HMKWEraN9V-lQ0B^vL4OPqdOq}&PDf=w2D!LBhPv_5x6^Qi za^BnNbVU@8=kTaVhAef(Lc+WYNnEWT5y){@+yyPc2Ju4HIG{^%eJc|3^m$hw<70xJ zl6;NA`|RJNcgg2^>g8Q7^O++IKAj-_Jozid4-3m35kF6uT&_MQd5rF3?8n#Dl#$VV zR@6#1U2b5wA?31O%Min@7~7Hp@mOO6@*Z23SL^vsQA z>0FEpH<_H$6dG)x*TuoI@g78=<~tTz>z1`%L)G`#38qYN2FO2_@UzK3kuXM^DWd3i zt`HZ`x<(k2+-zY5AT&;Hx)OZJi9bHn4@wmTb*0(yfi-T2i%sdRwq$V@*eUvB3sJCs zIzWoBwjvmmeWI92lrlwQHX`KF0jMH!mc$zfkSccs$w>s~k+Jh!8}Aq`TUO3I)i|5x z_K_?GHrQW)m6D= zUV7ar>^Ld*wCkRC+kG#49jLV-BMlvS*zi$Cy{Vm4Kgb_YqmvphQq#_EYS0F=%LUEj zL?<&4<3u2ClfXQ|CbQ_25>IlISuBiAp^PAPvI(6gF(6Dku@1V~y^;GZZbALGxbd&Z zg^BK8kPATfk=rNK`uv@1i`cOXXHKJF_ra#J2i!5D`P=^G=;i3;=;i3;=;i3;=>K;l z1Ajc=pV;snHAS8Y-Za&Q0004lX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmP!xqvQ%hAU z4t5Z6$WWauh>AFB6^c+H)C#RSn7s54nlvOSE{=k0!NH%!s)LKOt`4q(Aov5~9J6k5di;PO7sd*^W9eSpxYFwN>32Q=L_)5(OG&8>>zSM(s_R!C-+F(*kW_^z*e z1o(az=UM*u{#<=(-eN#NB%Wo4X%lY{PjA`==Y8TRE6FPHIq{fD4H7?cUGeyhbJ1mi zXGYCTdY(8+EEYRh>0nkeHR37an5yZNFJwJdId5^+DmB*XlfN*M*H@OgPBn}q7O?~g zA{5k6Mg=zFwCki;NYi=3$3NuyC2}d`Dua<@0aa*_T|f9A{GP2w3VS*31(gF|4nNZIQ?@9yrL+rM{O^ZNnc&vI-DMAGyC z000JJOGiWi000000Qp0^e*gdg32;bRa{vGi!~g&e!~vBn4jTXf00(qQO+^Rf2@DAg zFoSw((f|Meqe(kUpCE;5D2N0KiW1@YpkO6e zk-U+2*A9R@v6C~tPB2M|CI+BZGjQPneOk4L1-SCWFoFq)*pOa(hQg*NN&5lXhMLGn zNvpAW>JiyZgUwu2ita|xs+d3FMnE3p>`6d2#L`2Mj3Ij)SsAnu$KfpLPz&14*nG`l n?b@a;8vLA#nmGvnqu;_EwKVXHlyx1L00000NkvXXu0mjffElMx literal 0 HcmV?d00001