diff --git a/sdrbase/mainwindow.cpp b/sdrbase/mainwindow.cpp
index 482c99740..a89d506c9 100644
--- a/sdrbase/mainwindow.cpp
+++ b/sdrbase/mainwindow.cpp
@@ -1,1051 +1,1066 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
-// written by Christian Daniel //
-// //
-// 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 //
-// //
-// 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
-#include
-#include
-#include
-#include
-
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
-#include "device/devicesourceapi.h"
-#include "device/devicesinkapi.h"
-#include "audio/audiodeviceinfo.h"
-#include "gui/indicator.h"
-#include "gui/presetitem.h"
-#include "gui/addpresetdialog.h"
-#include "gui/pluginsdialog.h"
-#include "gui/aboutdialog.h"
-#include "gui/rollupwidget.h"
-#include "gui/channelwindow.h"
-#include "gui/audiodialog.h"
-#include "gui/samplingdevicecontrol.h"
-#include "gui/mypositiondialog.h"
-#include "dsp/dspengine.h"
-#include "dsp/spectrumvis.h"
-#include "dsp/dspcommands.h"
-#include "plugin/plugingui.h"
-#include "plugin/pluginapi.h"
-#include "plugin/plugingui.h"
-
-#include "gui/glspectrum.h"
-#include "gui/glspectrumgui.h"
-
-#include
-#include
-
-MainWindow::MainWindow(QWidget* parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow),
- m_masterTabIndex(0),
- m_settings(),
- m_dspEngine(DSPEngine::instance()),
- m_lastEngineState((DSPDeviceSourceEngine::State)-1),
- m_inputGUI(0),
- m_sampleRate(0),
- m_centerFrequency(0),
- m_sampleFileName(std::string("./test.sdriq"))
-{
- qDebug() << "MainWindow::MainWindow: start";
-
- m_settings.setAudioDeviceInfo(&m_audioDeviceInfo);
-
- ui->setupUi(this);
- createStatusBar();
-
- setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
- setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
- setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
- setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
-
- // work around broken Qt dock widget ordering
- removeDockWidget(ui->inputViewDock);
- removeDockWidget(ui->inputSelectDock);
- removeDockWidget(ui->spectraDisplayDock);
- removeDockWidget(ui->presetDock);
- removeDockWidget(ui->channelDock);
- addDockWidget(Qt::LeftDockWidgetArea, ui->inputSelectDock);
- addDockWidget(Qt::LeftDockWidgetArea, ui->inputViewDock);
- addDockWidget(Qt::LeftDockWidgetArea, ui->spectraDisplayDock);
- addDockWidget(Qt::LeftDockWidgetArea, ui->presetDock);
- addDockWidget(Qt::RightDockWidgetArea, ui->channelDock);
-
- ui->inputViewDock->show();
- ui->inputSelectDock->show();
- ui->spectraDisplayDock->show();
- ui->presetDock->show();
- ui->channelDock->show();
-
- ui->menu_Window->addAction(ui->inputViewDock->toggleViewAction());
- ui->menu_Window->addAction(ui->inputSelectDock->toggleViewAction());
- ui->menu_Window->addAction(ui->spectraDisplayDock->toggleViewAction());
- ui->menu_Window->addAction(ui->presetDock->toggleViewAction());
- ui->menu_Window->addAction(ui->channelDock->toggleViewAction());
-
- ui->tabInputsView->setStyleSheet("QWidget { background: rgb(50,50,50); } "
- "QToolButton::checked { background: rgb(128,70,0); } "
- "QComboBox::item:selected { color: rgb(255,140,0); } "
- "QTabWidget::pane { border: 1px solid #C06900; } "
- "QTabBar::tab:selected { background: rgb(128,70,0); }");
- ui->tabInputsSelect->setStyleSheet("QWidget { background: rgb(50,50,50); } "
- "QToolButton::checked { background: rgb(128,70,0); } "
- "QComboBox::item:selected { color: rgb(255,140,0); } "
- "QTabWidget::pane { border: 1px solid #808080; } "
- "QTabBar::tab:selected { background: rgb(100,100,100); }");
-
- m_pluginManager = new PluginManager(this);
- m_pluginManager->loadPlugins();
-
- connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection);
-
- connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
- m_statusTimer.start(1000);
-
- m_masterTimer.start(50);
-
- qDebug() << "MainWindow::MainWindow: add the first device...";
-
- addSourceDevice(); // add the first device
-
- qDebug() << "MainWindow::MainWindow: load settings...";
-
- loadSettings();
-
- qDebug() << "MainWindow::MainWindow: select SampleSource from settings...";
-
- int sampleSourceIndex = m_settings.getSourceIndex();
- sampleSourceIndex = m_pluginManager->selectSampleSourceByIndex(sampleSourceIndex, m_deviceUIs.back()->m_deviceSourceAPI);
-
- if (sampleSourceIndex < 0)
- {
- qCritical("MainWindow::MainWindow: no sample source. Exit");
- exit(0);
- }
-
- bool sampleSourceSignalsBlocked = m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(true);
- m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->setCurrentIndex(sampleSourceIndex);
- m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(sampleSourceSignalsBlocked);
-
- qDebug() << "MainWindow::MainWindow: load current preset settings...";
-
- loadPresetSettings(m_settings.getWorkingPreset(), 0);
-
- qDebug() << "MainWindow::MainWindow: apply settings...";
-
- applySettings();
-
- qDebug() << "MainWindow::MainWindow: update preset controls...";
-
- updatePresetControls();
-
- connect(ui->tabInputsView, SIGNAL(currentChanged(int)), this, SLOT(tabInputViewIndexChanged()));
-
- qDebug() << "MainWindow::MainWindow: end";
-}
-
-MainWindow::~MainWindow()
-{
- delete m_pluginManager;
- delete m_dateTimeWidget;
- delete m_showSystemWidget;
-
- delete ui;
-}
-
-void MainWindow::addSourceDevice()
-{
- DSPDeviceSourceEngine *dspDeviceSourceEngine = m_dspEngine->addDeviceSourceEngine();
- dspDeviceSourceEngine->start();
-
- uint dspDeviceSourceEngineUID = dspDeviceSourceEngine->getUID();
- char uidCStr[16];
- sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID);
-
- m_deviceUIs.push_back(new DeviceUISet(m_masterTimer));
- m_deviceUIs.back()->m_deviceSourceEngine = dspDeviceSourceEngine;
-
- int deviceTabIndex = m_deviceUIs.size()-1;
- char tabNameCStr[16];
- sprintf(tabNameCStr, "R%d", deviceTabIndex);
-
- DeviceSourceAPI *deviceSourceAPI = new DeviceSourceAPI(this, deviceTabIndex, dspDeviceSourceEngine, m_deviceUIs.back()->m_spectrum, m_deviceUIs.back()->m_channelWindow);
-
- m_deviceUIs.back()->m_deviceSourceAPI = deviceSourceAPI;
- m_deviceUIs.back()->m_samplingDeviceControl->setDeviceAPI(deviceSourceAPI);
- m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
- m_pluginManager->populateRxChannelComboBox(m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector());
-
- connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(on_channel_addClicked(bool)));
-
- dspDeviceSourceEngine->addSink(m_deviceUIs.back()->m_spectrumVis);
- ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
- ui->tabSpectraGUI->addTab(m_deviceUIs.back()->m_spectrumGUI, tabNameCStr);
- ui->tabChannels->addTab(m_deviceUIs.back()->m_channelWindow, tabNameCStr);
-
- bool sampleSourceSignalsBlocked = m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(true);
- m_pluginManager->duplicateLocalSampleSourceDevices(dspDeviceSourceEngineUID);
- m_pluginManager->fillSampleSourceSelector(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector(), dspDeviceSourceEngineUID);
-
- connect(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelectionConfirm(), SIGNAL(clicked(bool)), this, SLOT(on_sampleSource_confirmClicked(bool)));
-
- m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(sampleSourceSignalsBlocked);
- ui->tabInputsSelect->addTab(m_deviceUIs.back()->m_samplingDeviceControl, tabNameCStr);
- ui->tabInputsSelect->setTabToolTip(deviceTabIndex, QString(uidCStr));
-
- int sampleSourceIndex = m_pluginManager->selectSampleSourceBySerialOrSequence("sdrangel.samplesource.filesource", "0", 0, m_deviceUIs.back()->m_deviceSourceAPI);
-}
-
-void MainWindow::addSinkDevice()
-{
- DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
- dspDeviceSinkEngine->start();
-
- uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID();
- char uidCStr[16];
- sprintf(uidCStr, "UID:%d", dspDeviceSinkEngineUID);
-
- m_deviceUIs.push_back(new DeviceUISet(m_masterTimer));
- m_deviceUIs.back()->m_deviceSourceEngine = 0;
- m_deviceUIs.back()->m_deviceSinkEngine = dspDeviceSinkEngine;
-
- int deviceTabIndex = m_deviceUIs.size()-1;
- char tabNameCStr[16];
- sprintf(tabNameCStr, "T%d", deviceTabIndex);
-
- DeviceSinkAPI *deviceSinkAPI = new DeviceSinkAPI(this, deviceTabIndex, dspDeviceSinkEngine, m_deviceUIs.back()->m_spectrum, m_deviceUIs.back()->m_channelWindow);
-
- m_deviceUIs.back()->m_deviceSourceAPI = 0;
- m_deviceUIs.back()->m_deviceSinkAPI = deviceSinkAPI;
- m_deviceUIs.back()->m_samplingDeviceControl->setDeviceAPI(deviceSinkAPI);
- m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
- m_pluginManager->populateTxChannelComboBox(m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector());
-
- connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(on_channel_addClicked(bool)));
-
- dspDeviceSinkEngine->addSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
- ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
- ui->tabSpectraGUI->addTab(m_deviceUIs.back()->m_spectrumGUI, tabNameCStr);
- ui->tabChannels->addTab(m_deviceUIs.back()->m_channelWindow, tabNameCStr);
-
- bool sampleSourceSignalsBlocked = m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(true);
- m_pluginManager->duplicateLocalSampleSinkDevices(dspDeviceSinkEngineUID);
- m_pluginManager->fillSampleSinkSelector(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector(), dspDeviceSinkEngineUID);
-
- connect(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelectionConfirm(), SIGNAL(clicked(bool)), this, SLOT(on_sampleSink_confirmClicked(bool)));
-
- m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(sampleSourceSignalsBlocked);
- ui->tabInputsSelect->addTab(m_deviceUIs.back()->m_samplingDeviceControl, tabNameCStr);
- ui->tabInputsSelect->setTabToolTip(deviceTabIndex, QString(uidCStr));
-
- int sampleSinkIndex = m_pluginManager->selectSampleSinkBySerialOrSequence("sdrangel.samplesink.filesink", "0", 0, m_deviceUIs.back()->m_deviceSinkAPI);
-}
-
-void MainWindow::removeLastDevice()
-{
- if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab
- {
- DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine;
- lastDeviceEngine->stopAcquistion();
- lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis);
-
- ui->tabSpectraGUI->removeTab(ui->tabSpectraGUI->count() - 1);
- ui->tabSpectra->removeTab(ui->tabSpectra->count() - 1);
-
- m_deviceUIs.back()->m_deviceSourceAPI->freeAll();
- m_deviceUIs.back()->m_deviceSourceAPI->clearBuddiesLists(); // remove old API from buddies lists
-
- ui->tabChannels->removeTab(ui->tabChannels->count() - 1);
-
- ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1);
-
- m_deviceWidgetTabs.removeLast();m_pluginManager->loadPlugins();
- ui->tabInputsView->clear();
-
- for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
- {
- qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
- ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
- ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
- }
-
- delete m_deviceUIs.back();
-
- lastDeviceEngine->stop();
- m_dspEngine->removeLastDeviceSourceEngine();
- }
- else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab
- {
- DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine;
- lastDeviceEngine->stopGeneration();
- lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
-
- ui->tabSpectraGUI->removeTab(ui->tabSpectraGUI->count() - 1);
- ui->tabSpectra->removeTab(ui->tabSpectra->count() - 1);
-
- m_deviceUIs.back()->m_deviceSinkAPI->freeAll();
- m_deviceUIs.back()->m_deviceSinkAPI->clearBuddiesLists(); // remove old API from buddies lists
-
- ui->tabChannels->removeTab(ui->tabChannels->count() - 1);
-
- ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1);
-
- m_deviceWidgetTabs.removeLast();
- ui->tabInputsView->clear();
-
- for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
- {
- qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
- ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
- ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
- }
-
- delete m_deviceUIs.back();
-
- lastDeviceEngine->stop();
- m_dspEngine->removeLastDeviceSinkEngine();
- }
-
- m_deviceUIs.pop_back();
-}
-
-void MainWindow::addChannelRollup(int deviceTabIndex, QWidget* widget)
-{
- if (deviceTabIndex < ui->tabInputsView->count())
- {
- DeviceUISet *deviceUI = m_deviceUIs[deviceTabIndex];
- deviceUI->m_channelWindow->addRollupWidget(widget);
- ui->channelDock->show();
- ui->channelDock->raise();
- }
-}
-
-void MainWindow::addViewAction(QAction* action)
-{
- ui->menu_Window->addAction(action);
-}
-
-void MainWindow::setDeviceGUI(int deviceTabIndex, QWidget* gui, const QString& deviceDisplayName, bool sourceDevice)
-{
- char tabNameCStr[16];
-
- if (sourceDevice)
- {
- sprintf(tabNameCStr, "R%d", deviceTabIndex);
- }
- else
- {
- sprintf(tabNameCStr, "T%d", deviceTabIndex);
- }
-
- qDebug("MainWindow::setDeviceGUI: insert %s tab at %d", sourceDevice ? "Rx" : "Tx", deviceTabIndex);
-
- if (deviceTabIndex < m_deviceWidgetTabs.size())
- {
- m_deviceWidgetTabs[deviceTabIndex] = {gui, deviceDisplayName, QString(tabNameCStr)};
- }
- else
- {
- m_deviceWidgetTabs.append({gui, deviceDisplayName, QString(tabNameCStr)});
- }
-
- ui->tabInputsView->clear();
-
- for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
- {
- qDebug("MainWindow::setDeviceGUI: adding tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
- ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
- ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
- }
-
- ui->tabInputsView->setCurrentIndex(deviceTabIndex);
-}
-
-void MainWindow::loadSettings()
-{
- qDebug() << "MainWindow::loadSettings";
-
- m_settings.load();
- m_settings.sortPresets();
-
- for(int i = 0; i < m_settings.getPresetCount(); ++i)
- {
- addPresetToTree(m_settings.getPreset(i));
- }
-}
-
-void MainWindow::loadPresetSettings(const Preset* preset, int tabIndex)
-{
- qDebug("MainWindow::loadPresetSettings: preset [%s | %s]",
- qPrintable(preset->getGroup()),
- qPrintable(preset->getDescription()));
-
- if (tabIndex >= 0)
- {
- DeviceUISet *deviceUI = m_deviceUIs[tabIndex];
-
- if (deviceUI->m_deviceSourceEngine) // source device
- {
- deviceUI->m_spectrumGUI->deserialize(preset->getSpectrumConfig());
- deviceUI->m_deviceSourceAPI->loadSourceSettings(preset);
- deviceUI->m_deviceSourceAPI->loadChannelSettings(preset, &(m_pluginManager->m_pluginAPI));
- }
- else if (deviceUI->m_deviceSinkEngine) // sink device
- {
- deviceUI->m_spectrumGUI->deserialize(preset->getSpectrumConfig());
- deviceUI->m_deviceSinkAPI->loadSinkSettings(preset);
- deviceUI->m_deviceSinkAPI->loadChannelSettings(preset, &(m_pluginManager->m_pluginAPI));
- }
- }
-
- // has to be last step
- restoreState(preset->getLayout());
-}
-
-void MainWindow::savePresetSettings(Preset* preset, int tabIndex)
-{
- qDebug("MainWindow::savePresetSettings: preset [%s | %s]",
- qPrintable(preset->getGroup()),
- qPrintable(preset->getDescription()));
-
- // Save from currently selected source tab
- //int currentSourceTabIndex = ui->tabInputsView->currentIndex();
- DeviceUISet *deviceUI = m_deviceUIs[tabIndex];
-
- if (deviceUI->m_deviceSourceEngine) // source device
- {
- preset->setSpectrumConfig(deviceUI->m_spectrumGUI->serialize());
- preset->clearChannels();
- deviceUI->m_deviceSourceAPI->saveChannelSettings(preset);
- deviceUI->m_deviceSourceAPI->saveSourceSettings(preset);
- }
- else if (deviceUI->m_deviceSinkEngine) // sink device
- {
- preset->setSpectrumConfig(deviceUI->m_spectrumGUI->serialize());
- preset->clearChannels();
- preset->setSourcePreset(false);
- deviceUI->m_deviceSinkAPI->saveChannelSettings(preset);
- deviceUI->m_deviceSinkAPI->saveSinkSettings(preset);
- }
-
- preset->setLayout(saveState());
-}
-
-void MainWindow::createStatusBar()
-{
- QString qtVersionStr = QString("Qt %1 ").arg(QT_VERSION_STR);
-#if QT_VERSION >= 0x050400
- m_showSystemWidget = new QLabel("SDRangel v3.3.4 " + qtVersionStr + QSysInfo::prettyProductName(), this);
-#else
- m_showSystemWidget = new QLabel("SDRangel v3.3.4 " + qtVersionStr, this);
-#endif
- statusBar()->addPermanentWidget(m_showSystemWidget);
-
- m_dateTimeWidget = new QLabel(tr("Date"), this);
- m_dateTimeWidget->setToolTip(tr("Current date/time"));
- statusBar()->addPermanentWidget(m_dateTimeWidget);
-}
-
-void MainWindow::closeEvent(QCloseEvent*)
-{
-}
-
-void MainWindow::updatePresetControls()
-{
- ui->presetTree->resizeColumnToContents(0);
-
- if(ui->presetTree->currentItem() != 0)
- {
- ui->presetDelete->setEnabled(true);
- ui->presetLoad->setEnabled(true);
- }
- else
- {
- ui->presetDelete->setEnabled(false);
- ui->presetLoad->setEnabled(false);
- }
-}
-
-QTreeWidgetItem* MainWindow::addPresetToTree(const Preset* preset)
-{
- QTreeWidgetItem* group = 0;
-
- for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++)
- {
- if(ui->presetTree->topLevelItem(i)->text(0) == preset->getGroup())
- {
- group = ui->presetTree->topLevelItem(i);
- break;
- }
- }
-
- if(group == 0)
- {
- QStringList sl;
- sl.append(preset->getGroup());
- group = new QTreeWidgetItem(ui->presetTree, sl, PGroup);
- group->setFirstColumnSpanned(true);
- group->setExpanded(true);
- ui->presetTree->sortByColumn(0, Qt::AscendingOrder);
- }
-
- QStringList sl;
- sl.append(QString("%1").arg(preset->getCenterFrequency() / 1e6f, 0, 'f', 3)); // frequency column
- sl.append(QString("%1").arg(preset->isSourcePreset() ? 'R' : 'T')); // mode column
- sl.append(preset->getDescription()); // description column
- PresetItem* item = new PresetItem(group, sl, preset->getCenterFrequency(), PItem);
- item->setTextAlignment(0, Qt::AlignRight);
- item->setData(0, Qt::UserRole, qVariantFromValue(preset));
- ui->presetTree->resizeColumnToContents(0); // Resize frequency column to minimum
- ui->presetTree->resizeColumnToContents(1); // Resize mode column to minimum
-
- updatePresetControls();
- return item;
-}
-
-void MainWindow::applySettings()
-{
-}
-
-void MainWindow::handleMessages()
-{
- Message* message;
-
- while ((message = m_inputMessageQueue.pop()) != 0)
- {
- qDebug("MainWindow::handleMessages: message: %s", message->getIdentifier());
- delete message;
- }
-}
-
-void MainWindow::on_action_View_Fullscreen_toggled(bool checked)
-{
- if(checked)
- showFullScreen();
- else showNormal();
-}
-
-void MainWindow::on_presetSave_clicked()
-{
- QStringList groups;
- QString group;
- QString description = "";
- for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++)
- groups.append(ui->presetTree->topLevelItem(i)->text(0));
-
- QTreeWidgetItem* item = ui->presetTree->currentItem();
- if(item != 0) {
- if(item->type() == PGroup)
- group = item->text(0);
- else if(item->type() == PItem) {
- group = item->parent()->text(0);
- description = item->text(0);
- }
- }
-
- AddPresetDialog dlg(groups, group, this);
-
- if (description.length() > 0) {
- dlg.setDescription(description);
- }
-
- if(dlg.exec() == QDialog::Accepted) {
- Preset* preset = m_settings.newPreset(dlg.group(), dlg.description());
- savePresetSettings(preset, ui->tabInputsView->currentIndex());
-
- ui->presetTree->setCurrentItem(addPresetToTree(preset));
- }
-}
-
-void MainWindow::on_presetUpdate_clicked()
-{
- QTreeWidgetItem* item = ui->presetTree->currentItem();
-
- if(item != 0) {
- if(item->type() == PItem) {
- const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
- if (preset != 0) {
- Preset* preset_mod = const_cast(preset);
- savePresetSettings(preset_mod, ui->tabInputsView->currentIndex());
- }
- }
- }
-}
-
-void MainWindow::on_presetExport_clicked()
-{
- QTreeWidgetItem* item = ui->presetTree->currentItem();
-
- if(item != 0) {
- if(item->type() == PItem)
- {
- const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
- QString base64Str = preset->serialize().toBase64();
- QString fileName = QFileDialog::getSaveFileName(this,
- tr("Open preset export file"), ".", tr("Preset export files (*.prex)"));
-
- if (fileName != "")
- {
- QFileInfo fileInfo(fileName);
-
- if (fileInfo.suffix() != "prex") {
- fileName += ".prex";
- }
-
- QFile exportFile(fileName);
-
- if (exportFile.open(QIODevice::WriteOnly | QIODevice::Text))
- {
- QTextStream outstream(&exportFile);
- outstream << base64Str;
- exportFile.close();
- }
- else
- {
- QMessageBox::information(this, tr("Message"), tr("Cannot open file for writing"));
- }
- }
- }
- }
-}
-
-void MainWindow::on_presetImport_clicked()
-{
- QTreeWidgetItem* item = ui->presetTree->currentItem();
-
- if(item != 0)
- {
- QString group;
-
- if (item->type() == PGroup) {
- group = item->text(0);
- } else if (item->type() == PItem) {
- group = item->parent()->text(0);
- } else {
- return;
- }
-
- QString fileName = QFileDialog::getOpenFileName(this,
- tr("Open preset export file"), ".", tr("Preset export files (*.prex)"));
-
- if (fileName != "")
- {
- QFile exportFile(fileName);
-
- if (exportFile.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- QByteArray base64Str;
- QTextStream instream(&exportFile);
- instream >> base64Str;
- exportFile.close();
-
- Preset* preset = m_settings.newPreset("", "");
- preset->deserialize(QByteArray::fromBase64(base64Str));
- preset->setGroup(group); // override with current group
-
- ui->presetTree->setCurrentItem(addPresetToTree(preset));
- }
- else
- {
- QMessageBox::information(this, tr("Message"), tr("Cannot open file for reading"));
- }
- }
- }
-}
-
-void MainWindow::on_settingsSave_clicked()
-{
- savePresetSettings(m_settings.getWorkingPreset(), ui->tabInputsView->currentIndex());
- m_settings.save();
-}
-
-void MainWindow::on_presetLoad_clicked()
-{
- qDebug() << "MainWindow::on_presetLoad_clicked";
-
- QTreeWidgetItem* item = ui->presetTree->currentItem();
-
- if(item == 0)
- {
- qDebug("MainWindow::on_presetLoad_clicked: item null");
- updatePresetControls();
- return;
- }
-
- const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
-
- if(preset == 0)
- {
- qDebug("MainWindow::on_presetLoad_clicked: preset null");
- return;
- }
-
- loadPresetSettings(preset, ui->tabInputsView->currentIndex());
- applySettings();
-}
-
-void MainWindow::on_presetDelete_clicked()
-{
- QTreeWidgetItem* item = ui->presetTree->currentItem();
- if(item == 0) {
- updatePresetControls();
- return;
- }
- const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
- if(preset == 0)
- return;
-
- if(QMessageBox::question(this, tr("Delete Preset"), tr("Do you want to delete preset '%1'?").arg(preset->getDescription()), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
- delete item;
- m_settings.deletePreset(preset);
- }
-}
-
-void MainWindow::on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
-{
- updatePresetControls();
-}
-
-void MainWindow::on_presetTree_itemActivated(QTreeWidgetItem *item, int column)
-{
- on_presetLoad_clicked();
-}
-
-void MainWindow::on_action_Loaded_Plugins_triggered()
-{
- PluginsDialog pluginsDialog(m_pluginManager, this);
- pluginsDialog.exec();
-}
-
-void MainWindow::on_action_Audio_triggered()
-{
- AudioDialog audioDialog(&m_audioDeviceInfo, this);
- audioDialog.exec();
- m_dspEngine->setAudioInputVolume(m_audioDeviceInfo.getInputVolume());
- m_dspEngine->setAudioInputDeviceIndex(m_audioDeviceInfo.getInputDeviceIndex());
- m_dspEngine->setAudioOutputDeviceIndex(m_audioDeviceInfo.getOutputDeviceIndex());
-}
-
-void MainWindow::on_action_My_Position_triggered()
-{
- MyPositionDialog myPositionDialog(m_settings, this);
- myPositionDialog.exec();
-}
-
-void MainWindow::on_action_DV_Serial_triggered(bool checked)
-{
- m_dspEngine->setDVSerialSupport(checked);
-
- if (checked)
- {
- std::vector deviceNames;
- m_dspEngine->getDVSerialNames(deviceNames);
-
- if (deviceNames.size() == 0)
- {
- QMessageBox::information(this, tr("Message"), tr("No DV serial devices found"));
- }
- else
- {
- std::vector::iterator it = deviceNames.begin();
- std::string deviceNamesStr = "DV Serial devices found: ";
-
- while (it != deviceNames.end())
- {
- if (it != deviceNames.begin()) {
- deviceNamesStr += ",";
- }
-
- deviceNamesStr += *it;
- ++it;
- }
-
- QMessageBox::information(this, tr("Message"), tr(deviceNamesStr.c_str()));
- }
- }
-}
-
-void MainWindow::on_sampleSource_confirmClicked(bool checked)
-{
- // Do it in the currently selected source tab
- int currentSourceTabIndex = ui->tabInputsSelect->currentIndex();
-
- if (currentSourceTabIndex >= 0)
- {
- qDebug("MainWindow::on_sampleSource_confirmClicked: tab at %d", currentSourceTabIndex);
- DeviceUISet *deviceUI = m_deviceUIs[currentSourceTabIndex];
- deviceUI->m_deviceSourceAPI->saveSourceSettings(m_settings.getWorkingPreset()); // save old API settings
- int selectedComboIndex = deviceUI->m_samplingDeviceControl->getDeviceSelector()->currentIndex();
- void *devicePtr = deviceUI->m_samplingDeviceControl->getDeviceSelector()->itemData(selectedComboIndex).value();
- deviceUI->m_deviceSourceAPI->stopAcquisition();
- deviceUI->m_deviceSourceAPI->clearBuddiesLists(); // clear old API buddies lists
- m_pluginManager->selectSampleSourceByDevice(devicePtr, deviceUI->m_deviceSourceAPI); // sets the new API
- deviceUI->m_deviceSourceAPI->loadSourceSettings(m_settings.getWorkingPreset()); // load new API settings
-
- // add to buddies list
- std::vector::iterator it = m_deviceUIs.begin();
- 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_deviceSourceAPI->getHardwareId() == (*it)->m_deviceSourceAPI->getHardwareId()) &&
- (deviceUI->m_deviceSourceAPI->getSampleSourceSerial() == (*it)->m_deviceSourceAPI->getSampleSourceSerial()))
- {
- (*it)->m_deviceSourceAPI->addSourceBuddy(deviceUI->m_deviceSourceAPI);
- }
- }
-
- if ((*it)->m_deviceSinkEngine) // it is a sink device
- {
- if ((deviceUI->m_deviceSourceAPI->getHardwareId() == (*it)->m_deviceSinkAPI->getHardwareId()) &&
- (deviceUI->m_deviceSourceAPI->getSampleSourceSerial() == (*it)->m_deviceSinkAPI->getSampleSinkSerial()))
- {
- (*it)->m_deviceSinkAPI->addSourceBuddy(deviceUI->m_deviceSourceAPI);
- }
- }
- }
- }
-
- if (currentSourceTabIndex == 0)
- {
- m_settings.setSourceIndex(deviceUI->m_samplingDeviceControl->getDeviceSelector()->currentIndex());
- }
- }
-}
-
-void MainWindow::on_sampleSink_confirmClicked(bool checked)
-{
- // Do it in the currently selected source tab
- int currentSinkTabIndex = ui->tabInputsSelect->currentIndex();
-
- if (currentSinkTabIndex >= 0)
- {
- qDebug("MainWindow::on_sampleSink_confirmClicked: tab at %d", currentSinkTabIndex);
- DeviceUISet *deviceUI = m_deviceUIs[currentSinkTabIndex];
- deviceUI->m_deviceSinkAPI->saveSinkSettings(m_settings.getWorkingPreset()); // save old API settings
- int selectedComboIndex = deviceUI->m_samplingDeviceControl->getDeviceSelector()->currentIndex();
- void *devicePtr = deviceUI->m_samplingDeviceControl->getDeviceSelector()->itemData(selectedComboIndex).value();
- deviceUI->m_deviceSinkAPI->stopGeneration();
- deviceUI->m_deviceSinkAPI->clearBuddiesLists(); // remove old API from buddies lists
- m_pluginManager->selectSampleSinkByDevice(devicePtr, deviceUI->m_deviceSinkAPI); // sets the new API
- deviceUI->m_deviceSinkAPI->loadSinkSettings(m_settings.getWorkingPreset()); // load new API settings
-
- // add to buddies list
- std::vector::iterator it = m_deviceUIs.begin();
- 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_deviceSinkAPI->getHardwareId() == (*it)->m_deviceSourceAPI->getHardwareId()) &&
- (deviceUI->m_deviceSinkAPI->getSampleSinkSerial() == (*it)->m_deviceSourceAPI->getSampleSourceSerial()))
- {
- (*it)->m_deviceSourceAPI->addSinkBuddy(deviceUI->m_deviceSinkAPI);
- }
- }
-
- if ((*it)->m_deviceSinkEngine) // it is a sink device
- {
- if ((deviceUI->m_deviceSinkAPI->getHardwareId() == (*it)->m_deviceSinkAPI->getHardwareId()) &&
- (deviceUI->m_deviceSinkAPI->getSampleSinkSerial() == (*it)->m_deviceSinkAPI->getSampleSinkSerial()))
- {
- (*it)->m_deviceSinkAPI->addSinkBuddy(deviceUI->m_deviceSinkAPI);
- }
- }
- }
- }
- }
-}
-
-void MainWindow::on_channel_addClicked(bool checked)
-{
- // Do it in the currently selected source tab
- int currentSourceTabIndex = ui->tabInputsSelect->currentIndex();
-
- if (currentSourceTabIndex >= 0)
- {
- DeviceUISet *deviceUI = m_deviceUIs[currentSourceTabIndex];
-
- if (deviceUI->m_deviceSourceEngine) // source device => Rx channels
- {
- m_pluginManager->createRxChannelInstance(deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI->m_deviceSourceAPI);
- }
- else if (deviceUI->m_deviceSinkEngine) // sink device => Tx channels
- {
- uint32_t nbSources = deviceUI->m_deviceSinkAPI->getNumberOfSources();
-
- if (nbSources > 0) {
- QMessageBox::information(this, tr("Message"), tr("%1 channel(s) already in use. Multiple transmission channels is experimental. You may experience performance problems").arg(nbSources));
- }
-
- m_pluginManager->createTxChannelInstance(deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI->m_deviceSinkAPI);
- }
- }
-
-}
-
-void MainWindow::on_action_About_triggered()
-{
- AboutDialog dlg(this);
- dlg.exec();
-}
-
-void MainWindow::on_action_addSourceDevice_triggered()
-{
- addSourceDevice();
-}
-
-void MainWindow::on_action_addSinkDevice_triggered()
-{
- addSinkDevice();
-}
-
-void MainWindow::on_action_removeLastDevice_triggered()
-{
- if (m_deviceUIs.size() > 1)
- {
- removeLastDevice();
- }
-}
-
-void MainWindow::on_action_reloadDevices_triggered()
-{
- // all devices must be stopped
- std::vector::iterator it = m_deviceUIs.begin();
- for (; it != m_deviceUIs.end(); ++it)
- {
- if ((*it)->m_deviceSourceEngine) // it is a source device
- {
- if ((*it)->m_deviceSourceEngine->state() == DSPDeviceSourceEngine::StRunning)
- {
- QMessageBox::information(this, tr("Message"), tr("Stop all devices for reload to take effect"));
- return;
- }
- }
-
- if ((*it)->m_deviceSinkEngine) // it is a sink device
- {
- if ((*it)->m_deviceSinkEngine->state() == DSPDeviceSinkEngine::StRunning)
- {
- QMessageBox::information(this, tr("Message"), tr("Stop all devices for reload to take effect"));
- return;
- }
- }
- }
-
- // re-scan devices
- m_pluginManager->updateSampleSourceDevices();
- m_pluginManager->updateSampleSinkDevices();
-
- // re-populate device selectors keeping the same selection
- it = m_deviceUIs.begin();
- for (; it != m_deviceUIs.end(); ++it)
- {
- if ((*it)->m_deviceSourceEngine) // it is a source device
- {
- QComboBox *deviceSelectorComboBox = (*it)->m_samplingDeviceControl->getDeviceSelector();
- bool sampleSourceSignalsBlocked = deviceSelectorComboBox->blockSignals(true);
- m_pluginManager->fillSampleSourceSelector(deviceSelectorComboBox, (*it)->m_deviceSourceEngine->getUID());
- int newIndex = m_pluginManager->getSampleSourceSelectorIndex(deviceSelectorComboBox, (*it)->m_deviceSourceAPI);
- deviceSelectorComboBox->setCurrentIndex(newIndex);
- deviceSelectorComboBox->blockSignals(sampleSourceSignalsBlocked);
- }
-
- if ((*it)->m_deviceSinkEngine) // it is a sink device
- {
- QComboBox *deviceSelectorComboBox = (*it)->m_samplingDeviceControl->getDeviceSelector();
- bool sampleSinkSignalsBlocked = deviceSelectorComboBox->blockSignals(true);
- m_pluginManager->fillSampleSinkSelector(deviceSelectorComboBox, (*it)->m_deviceSinkEngine->getUID());
- int newIndex = m_pluginManager->getSampleSinkSelectorIndex(deviceSelectorComboBox, (*it)->m_deviceSinkAPI);
- deviceSelectorComboBox->setCurrentIndex(newIndex);
- deviceSelectorComboBox->blockSignals(sampleSinkSignalsBlocked);
- }
- }
-}
-
-void MainWindow::on_action_Exit_triggered()
-{
- savePresetSettings(m_settings.getWorkingPreset(), 0);
- m_settings.save();
-
- while (m_deviceUIs.size() > 0)
- {
- removeLastDevice();
- }
-}
-
-void MainWindow::tabInputViewIndexChanged()
-{
- int inputViewIndex = ui->tabInputsView->currentIndex();
-
- if ((inputViewIndex >= 0) && (m_masterTabIndex >= 0) && (inputViewIndex != m_masterTabIndex))
- {
- DeviceUISet *deviceUI = m_deviceUIs[inputViewIndex];
- DeviceUISet *lastdeviceUI = m_deviceUIs[m_masterTabIndex];
- lastdeviceUI->m_mainWindowState = saveState();
- restoreState(deviceUI->m_mainWindowState);
- m_masterTabIndex = inputViewIndex;
- }
-
- ui->tabSpectra->setCurrentIndex(inputViewIndex);
- ui->tabChannels->setCurrentIndex(inputViewIndex);
- ui->tabInputsSelect->setCurrentIndex(inputViewIndex);
- ui->tabSpectraGUI->setCurrentIndex(inputViewIndex);
-}
-
-void MainWindow::updateStatus()
-{
- m_dateTimeWidget->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss t"));
-}
-
-MainWindow::DeviceUISet::DeviceUISet(QTimer& timer)
-{
- m_spectrum = new GLSpectrum;
- m_spectrumVis = new SpectrumVis(m_spectrum);
- m_spectrum->connectTimer(timer);
- m_spectrumGUI = new GLSpectrumGUI;
- m_spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, m_spectrum);
- m_channelWindow = new ChannelWindow;
- m_samplingDeviceControl = new SamplingDeviceControl;
- m_deviceSourceEngine = 0;
- m_deviceSourceAPI = 0;
- m_deviceSinkEngine = 0;
- m_deviceSinkAPI = 0;
-
- // m_spectrum needs to have its font to be set since it cannot be inherited from the main window
- QFont font;
- font.setFamily(QStringLiteral("Sans Serif"));
- font.setPointSize(9);
- m_spectrum->setFont(font);
-
-}
-
-MainWindow::DeviceUISet::~DeviceUISet()
-{
- delete m_samplingDeviceControl;
- delete m_channelWindow;
- delete m_spectrumGUI;
- delete m_spectrumVis;
- delete m_spectrum;
-}
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
+// written by Christian Daniel //
+// //
+// 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 //
+// //
+// 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
+#include
+#include
+#include
+#include
+
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "device/devicesourceapi.h"
+#include "device/devicesinkapi.h"
+#include "audio/audiodeviceinfo.h"
+#include "gui/indicator.h"
+#include "gui/presetitem.h"
+#include "gui/addpresetdialog.h"
+#include "gui/pluginsdialog.h"
+#include "gui/aboutdialog.h"
+#include "gui/rollupwidget.h"
+#include "gui/channelwindow.h"
+#include "gui/audiodialog.h"
+#include "gui/samplingdevicecontrol.h"
+#include "gui/mypositiondialog.h"
+#include "dsp/dspengine.h"
+#include "dsp/spectrumvis.h"
+#include "dsp/dspcommands.h"
+#include "plugin/plugingui.h"
+#include "plugin/pluginapi.h"
+#include "plugin/plugingui.h"
+
+#include "gui/glspectrum.h"
+#include "gui/glspectrumgui.h"
+
+#include
+#include
+
+MainWindow::MainWindow(QWidget* parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ m_masterTabIndex(0),
+ m_settings(),
+ m_dspEngine(DSPEngine::instance()),
+ m_lastEngineState((DSPDeviceSourceEngine::State)-1),
+ m_inputGUI(0),
+ m_sampleRate(0),
+ m_centerFrequency(0),
+ m_sampleFileName(std::string("./test.sdriq"))
+{
+ qDebug() << "MainWindow::MainWindow: start";
+
+ m_settings.setAudioDeviceInfo(&m_audioDeviceInfo);
+
+ ui->setupUi(this);
+ createStatusBar();
+
+ setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
+ setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+ setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
+ setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+
+ // work around broken Qt dock widget ordering
+ removeDockWidget(ui->inputViewDock);
+ removeDockWidget(ui->inputSelectDock);
+ removeDockWidget(ui->spectraDisplayDock);
+ removeDockWidget(ui->presetDock);
+ removeDockWidget(ui->channelDock);
+ addDockWidget(Qt::LeftDockWidgetArea, ui->inputSelectDock);
+ addDockWidget(Qt::LeftDockWidgetArea, ui->inputViewDock);
+ addDockWidget(Qt::LeftDockWidgetArea, ui->spectraDisplayDock);
+ addDockWidget(Qt::LeftDockWidgetArea, ui->presetDock);
+ addDockWidget(Qt::RightDockWidgetArea, ui->channelDock);
+
+ ui->inputViewDock->show();
+ ui->inputSelectDock->show();
+ ui->spectraDisplayDock->show();
+ ui->presetDock->show();
+ ui->channelDock->show();
+
+ ui->menu_Window->addAction(ui->inputViewDock->toggleViewAction());
+ ui->menu_Window->addAction(ui->inputSelectDock->toggleViewAction());
+ ui->menu_Window->addAction(ui->spectraDisplayDock->toggleViewAction());
+ ui->menu_Window->addAction(ui->presetDock->toggleViewAction());
+ ui->menu_Window->addAction(ui->channelDock->toggleViewAction());
+
+ ui->tabInputsView->setStyleSheet("QWidget { background: rgb(50,50,50); } "
+ "QToolButton::checked { background: rgb(128,70,0); } "
+ "QComboBox::item:selected { color: rgb(255,140,0); } "
+ "QTabWidget::pane { border: 1px solid #C06900; } "
+ "QTabBar::tab:selected { background: rgb(128,70,0); }");
+ ui->tabInputsSelect->setStyleSheet("QWidget { background: rgb(50,50,50); } "
+ "QToolButton::checked { background: rgb(128,70,0); } "
+ "QComboBox::item:selected { color: rgb(255,140,0); } "
+ "QTabWidget::pane { border: 1px solid #808080; } "
+ "QTabBar::tab:selected { background: rgb(100,100,100); }");
+
+ m_pluginManager = new PluginManager(this);
+ m_pluginManager->loadPlugins();
+
+ connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection);
+
+ connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
+ m_statusTimer.start(1000);
+
+ m_masterTimer.start(50);
+
+ qDebug() << "MainWindow::MainWindow: add the first device...";
+
+ addSourceDevice(); // add the first device
+
+ qDebug() << "MainWindow::MainWindow: load settings...";
+
+ loadSettings();
+
+ qDebug() << "MainWindow::MainWindow: select SampleSource from settings...";
+
+ int sampleSourceIndex = m_settings.getSourceIndex();
+ sampleSourceIndex = m_pluginManager->selectSampleSourceByIndex(sampleSourceIndex, m_deviceUIs.back()->m_deviceSourceAPI);
+
+ if (sampleSourceIndex < 0)
+ {
+ qCritical("MainWindow::MainWindow: no sample source. Exit");
+ exit(0);
+ }
+
+ bool sampleSourceSignalsBlocked = m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(true);
+ m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->setCurrentIndex(sampleSourceIndex);
+ m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(sampleSourceSignalsBlocked);
+
+ qDebug() << "MainWindow::MainWindow: load current preset settings...";
+
+ loadPresetSettings(m_settings.getWorkingPreset(), 0);
+
+ qDebug() << "MainWindow::MainWindow: apply settings...";
+
+ applySettings();
+
+ qDebug() << "MainWindow::MainWindow: update preset controls...";
+
+ updatePresetControls();
+
+ connect(ui->tabInputsView, SIGNAL(currentChanged(int)), this, SLOT(tabInputViewIndexChanged()));
+
+ qDebug() << "MainWindow::MainWindow: end";
+}
+
+MainWindow::~MainWindow()
+{
+ delete m_pluginManager;
+ delete m_dateTimeWidget;
+ delete m_showSystemWidget;
+
+ delete ui;
+}
+
+void MainWindow::addSourceDevice()
+{
+ DSPDeviceSourceEngine *dspDeviceSourceEngine = m_dspEngine->addDeviceSourceEngine();
+ dspDeviceSourceEngine->start();
+
+ uint dspDeviceSourceEngineUID = dspDeviceSourceEngine->getUID();
+ char uidCStr[16];
+ sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID);
+
+ m_deviceUIs.push_back(new DeviceUISet(m_masterTimer));
+ m_deviceUIs.back()->m_deviceSourceEngine = dspDeviceSourceEngine;
+
+ int deviceTabIndex = m_deviceUIs.size()-1;
+ char tabNameCStr[16];
+ sprintf(tabNameCStr, "R%d", deviceTabIndex);
+
+ DeviceSourceAPI *deviceSourceAPI = new DeviceSourceAPI(this, deviceTabIndex, dspDeviceSourceEngine, m_deviceUIs.back()->m_spectrum, m_deviceUIs.back()->m_channelWindow);
+
+ m_deviceUIs.back()->m_deviceSourceAPI = deviceSourceAPI;
+ m_deviceUIs.back()->m_samplingDeviceControl->setDeviceAPI(deviceSourceAPI);
+ m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
+ m_pluginManager->populateRxChannelComboBox(m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector());
+
+ connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(on_channel_addClicked(bool)));
+
+ dspDeviceSourceEngine->addSink(m_deviceUIs.back()->m_spectrumVis);
+ ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
+ ui->tabSpectraGUI->addTab(m_deviceUIs.back()->m_spectrumGUI, tabNameCStr);
+ ui->tabChannels->addTab(m_deviceUIs.back()->m_channelWindow, tabNameCStr);
+
+ bool sampleSourceSignalsBlocked = m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(true);
+ m_pluginManager->duplicateLocalSampleSourceDevices(dspDeviceSourceEngineUID);
+ m_pluginManager->fillSampleSourceSelector(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector(), dspDeviceSourceEngineUID);
+
+ connect(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelectionConfirm(), SIGNAL(clicked(bool)), this, SLOT(on_sampleSource_confirmClicked(bool)));
+
+ m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(sampleSourceSignalsBlocked);
+ ui->tabInputsSelect->addTab(m_deviceUIs.back()->m_samplingDeviceControl, tabNameCStr);
+ ui->tabInputsSelect->setTabToolTip(deviceTabIndex, QString(uidCStr));
+
+ int sampleSourceIndex = m_pluginManager->selectSampleSourceBySerialOrSequence("sdrangel.samplesource.filesource", "0", 0, m_deviceUIs.back()->m_deviceSourceAPI);
+}
+
+void MainWindow::addSinkDevice()
+{
+ DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
+ dspDeviceSinkEngine->start();
+
+ uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID();
+ char uidCStr[16];
+ sprintf(uidCStr, "UID:%d", dspDeviceSinkEngineUID);
+
+ m_deviceUIs.push_back(new DeviceUISet(m_masterTimer));
+ m_deviceUIs.back()->m_deviceSourceEngine = 0;
+ m_deviceUIs.back()->m_deviceSinkEngine = dspDeviceSinkEngine;
+
+ int deviceTabIndex = m_deviceUIs.size()-1;
+ char tabNameCStr[16];
+ sprintf(tabNameCStr, "T%d", deviceTabIndex);
+
+ DeviceSinkAPI *deviceSinkAPI = new DeviceSinkAPI(this, deviceTabIndex, dspDeviceSinkEngine, m_deviceUIs.back()->m_spectrum, m_deviceUIs.back()->m_channelWindow);
+
+ m_deviceUIs.back()->m_deviceSourceAPI = 0;
+ m_deviceUIs.back()->m_deviceSinkAPI = deviceSinkAPI;
+ m_deviceUIs.back()->m_samplingDeviceControl->setDeviceAPI(deviceSinkAPI);
+ m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
+ m_pluginManager->populateTxChannelComboBox(m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector());
+
+ connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(on_channel_addClicked(bool)));
+
+ dspDeviceSinkEngine->addSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
+ ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
+ ui->tabSpectraGUI->addTab(m_deviceUIs.back()->m_spectrumGUI, tabNameCStr);
+ ui->tabChannels->addTab(m_deviceUIs.back()->m_channelWindow, tabNameCStr);
+
+ bool sampleSourceSignalsBlocked = m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(true);
+ m_pluginManager->duplicateLocalSampleSinkDevices(dspDeviceSinkEngineUID);
+ m_pluginManager->fillSampleSinkSelector(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector(), dspDeviceSinkEngineUID);
+
+ connect(m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelectionConfirm(), SIGNAL(clicked(bool)), this, SLOT(on_sampleSink_confirmClicked(bool)));
+
+ m_deviceUIs.back()->m_samplingDeviceControl->getDeviceSelector()->blockSignals(sampleSourceSignalsBlocked);
+ ui->tabInputsSelect->addTab(m_deviceUIs.back()->m_samplingDeviceControl, tabNameCStr);
+ ui->tabInputsSelect->setTabToolTip(deviceTabIndex, QString(uidCStr));
+
+ int sampleSinkIndex = m_pluginManager->selectSampleSinkBySerialOrSequence("sdrangel.samplesink.filesink", "0", 0, m_deviceUIs.back()->m_deviceSinkAPI);
+}
+
+void MainWindow::removeLastDevice()
+{
+ if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab
+ {
+ DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine;
+ lastDeviceEngine->stopAcquistion();
+ lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis);
+
+ ui->tabSpectraGUI->removeTab(ui->tabSpectraGUI->count() - 1);
+ ui->tabSpectra->removeTab(ui->tabSpectra->count() - 1);
+
+ m_deviceUIs.back()->m_deviceSourceAPI->freeAll();
+ m_deviceUIs.back()->m_deviceSourceAPI->clearBuddiesLists(); // remove old API from buddies lists
+
+ ui->tabChannels->removeTab(ui->tabChannels->count() - 1);
+
+ ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1);
+
+ m_deviceWidgetTabs.removeLast();m_pluginManager->loadPlugins();
+ ui->tabInputsView->clear();
+
+ for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
+ {
+ qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
+ ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
+ ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
+ }
+
+ delete m_deviceUIs.back();
+
+ lastDeviceEngine->stop();
+ m_dspEngine->removeLastDeviceSourceEngine();
+ }
+ else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab
+ {
+ DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine;
+ lastDeviceEngine->stopGeneration();
+ lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
+
+ ui->tabSpectraGUI->removeTab(ui->tabSpectraGUI->count() - 1);
+ ui->tabSpectra->removeTab(ui->tabSpectra->count() - 1);
+
+ m_deviceUIs.back()->m_deviceSinkAPI->freeAll();
+ m_deviceUIs.back()->m_deviceSinkAPI->clearBuddiesLists(); // remove old API from buddies lists
+
+ ui->tabChannels->removeTab(ui->tabChannels->count() - 1);
+
+ ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1);
+
+ m_deviceWidgetTabs.removeLast();
+ ui->tabInputsView->clear();
+
+ for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
+ {
+ qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
+ ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
+ ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
+ }
+
+ delete m_deviceUIs.back();
+
+ lastDeviceEngine->stop();
+ m_dspEngine->removeLastDeviceSinkEngine();
+ }
+
+ m_deviceUIs.pop_back();
+}
+
+void MainWindow::addChannelRollup(int deviceTabIndex, QWidget* widget)
+{
+ if (deviceTabIndex < ui->tabInputsView->count())
+ {
+ DeviceUISet *deviceUI = m_deviceUIs[deviceTabIndex];
+ deviceUI->m_channelWindow->addRollupWidget(widget);
+ ui->channelDock->show();
+ ui->channelDock->raise();
+ }
+}
+
+void MainWindow::addViewAction(QAction* action)
+{
+ ui->menu_Window->addAction(action);
+}
+
+void MainWindow::setDeviceGUI(int deviceTabIndex, QWidget* gui, const QString& deviceDisplayName, bool sourceDevice)
+{
+ char tabNameCStr[16];
+
+ if (sourceDevice)
+ {
+ sprintf(tabNameCStr, "R%d", deviceTabIndex);
+ }
+ else
+ {
+ sprintf(tabNameCStr, "T%d", deviceTabIndex);
+ }
+
+ qDebug("MainWindow::setDeviceGUI: insert %s tab at %d", sourceDevice ? "Rx" : "Tx", deviceTabIndex);
+
+ if (deviceTabIndex < m_deviceWidgetTabs.size())
+ {
+ m_deviceWidgetTabs[deviceTabIndex] = {gui, deviceDisplayName, QString(tabNameCStr)};
+ }
+ else
+ {
+ m_deviceWidgetTabs.append({gui, deviceDisplayName, QString(tabNameCStr)});
+ }
+
+ ui->tabInputsView->clear();
+
+ for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
+ {
+ qDebug("MainWindow::setDeviceGUI: adding tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
+ ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
+ ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
+ }
+
+ ui->tabInputsView->setCurrentIndex(deviceTabIndex);
+}
+
+void MainWindow::loadSettings()
+{
+ qDebug() << "MainWindow::loadSettings";
+
+ m_settings.load();
+ m_settings.sortPresets();
+
+ for(int i = 0; i < m_settings.getPresetCount(); ++i)
+ {
+ addPresetToTree(m_settings.getPreset(i));
+ }
+}
+
+void MainWindow::loadPresetSettings(const Preset* preset, int tabIndex)
+{
+ qDebug("MainWindow::loadPresetSettings: preset [%s | %s]",
+ qPrintable(preset->getGroup()),
+ qPrintable(preset->getDescription()));
+
+ if (tabIndex >= 0)
+ {
+ DeviceUISet *deviceUI = m_deviceUIs[tabIndex];
+
+ if (deviceUI->m_deviceSourceEngine) // source device
+ {
+ deviceUI->m_spectrumGUI->deserialize(preset->getSpectrumConfig());
+ deviceUI->m_deviceSourceAPI->loadSourceSettings(preset);
+ deviceUI->m_deviceSourceAPI->loadChannelSettings(preset, &(m_pluginManager->m_pluginAPI));
+ }
+ else if (deviceUI->m_deviceSinkEngine) // sink device
+ {
+ deviceUI->m_spectrumGUI->deserialize(preset->getSpectrumConfig());
+ deviceUI->m_deviceSinkAPI->loadSinkSettings(preset);
+ deviceUI->m_deviceSinkAPI->loadChannelSettings(preset, &(m_pluginManager->m_pluginAPI));
+ }
+ }
+
+ // has to be last step
+ restoreState(preset->getLayout());
+}
+
+void MainWindow::savePresetSettings(Preset* preset, int tabIndex)
+{
+ qDebug("MainWindow::savePresetSettings: preset [%s | %s]",
+ qPrintable(preset->getGroup()),
+ qPrintable(preset->getDescription()));
+
+ // Save from currently selected source tab
+ //int currentSourceTabIndex = ui->tabInputsView->currentIndex();
+ DeviceUISet *deviceUI = m_deviceUIs[tabIndex];
+
+ if (deviceUI->m_deviceSourceEngine) // source device
+ {
+ preset->setSpectrumConfig(deviceUI->m_spectrumGUI->serialize());
+ preset->clearChannels();
+ deviceUI->m_deviceSourceAPI->saveChannelSettings(preset);
+ deviceUI->m_deviceSourceAPI->saveSourceSettings(preset);
+ }
+ else if (deviceUI->m_deviceSinkEngine) // sink device
+ {
+ preset->setSpectrumConfig(deviceUI->m_spectrumGUI->serialize());
+ preset->clearChannels();
+ preset->setSourcePreset(false);
+ deviceUI->m_deviceSinkAPI->saveChannelSettings(preset);
+ deviceUI->m_deviceSinkAPI->saveSinkSettings(preset);
+ }
+
+ preset->setLayout(saveState());
+}
+
+void MainWindow::createStatusBar()
+{
+ QString qtVersionStr = QString("Qt %1 ").arg(QT_VERSION_STR);
+#if QT_VERSION >= 0x050400
+ m_showSystemWidget = new QLabel("SDRangel v3.3.4 " + qtVersionStr + QSysInfo::prettyProductName(), this);
+#else
+ m_showSystemWidget = new QLabel("SDRangel v3.3.4 " + qtVersionStr, this);
+#endif
+ statusBar()->addPermanentWidget(m_showSystemWidget);
+
+ m_dateTimeWidget = new QLabel(tr("Date"), this);
+ m_dateTimeWidget->setToolTip(tr("Current date/time"));
+ statusBar()->addPermanentWidget(m_dateTimeWidget);
+}
+
+void MainWindow::closeEvent(QCloseEvent*)
+{
+}
+
+void MainWindow::updatePresetControls()
+{
+ ui->presetTree->resizeColumnToContents(0);
+
+ if(ui->presetTree->currentItem() != 0)
+ {
+ ui->presetDelete->setEnabled(true);
+ ui->presetLoad->setEnabled(true);
+ }
+ else
+ {
+ ui->presetDelete->setEnabled(false);
+ ui->presetLoad->setEnabled(false);
+ }
+}
+
+QTreeWidgetItem* MainWindow::addPresetToTree(const Preset* preset)
+{
+ QTreeWidgetItem* group = 0;
+
+ for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++)
+ {
+ if(ui->presetTree->topLevelItem(i)->text(0) == preset->getGroup())
+ {
+ group = ui->presetTree->topLevelItem(i);
+ break;
+ }
+ }
+
+ if(group == 0)
+ {
+ QStringList sl;
+ sl.append(preset->getGroup());
+ group = new QTreeWidgetItem(ui->presetTree, sl, PGroup);
+ group->setFirstColumnSpanned(true);
+ group->setExpanded(true);
+ ui->presetTree->sortByColumn(0, Qt::AscendingOrder);
+ }
+
+ QStringList sl;
+ sl.append(QString("%1").arg(preset->getCenterFrequency() / 1e6f, 0, 'f', 3)); // frequency column
+ sl.append(QString("%1").arg(preset->isSourcePreset() ? 'R' : 'T')); // mode column
+ sl.append(preset->getDescription()); // description column
+ PresetItem* item = new PresetItem(group, sl, preset->getCenterFrequency(), PItem);
+ item->setTextAlignment(0, Qt::AlignRight);
+ item->setData(0, Qt::UserRole, qVariantFromValue(preset));
+ ui->presetTree->resizeColumnToContents(0); // Resize frequency column to minimum
+ ui->presetTree->resizeColumnToContents(1); // Resize mode column to minimum
+
+ updatePresetControls();
+ return item;
+}
+
+void MainWindow::applySettings()
+{
+}
+
+void MainWindow::handleMessages()
+{
+ Message* message;
+
+ while ((message = m_inputMessageQueue.pop()) != 0)
+ {
+ qDebug("MainWindow::handleMessages: message: %s", message->getIdentifier());
+ delete message;
+ }
+}
+
+void MainWindow::on_action_View_Fullscreen_toggled(bool checked)
+{
+ if(checked)
+ showFullScreen();
+ else showNormal();
+}
+
+void MainWindow::on_presetSave_clicked()
+{
+ QStringList groups;
+ QString group;
+ QString description = "";
+ for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++)
+ groups.append(ui->presetTree->topLevelItem(i)->text(0));
+
+ QTreeWidgetItem* item = ui->presetTree->currentItem();
+ if(item != 0) {
+ if(item->type() == PGroup)
+ group = item->text(0);
+ else if(item->type() == PItem) {
+ group = item->parent()->text(0);
+ description = item->text(0);
+ }
+ }
+
+ AddPresetDialog dlg(groups, group, this);
+
+ if (description.length() > 0) {
+ dlg.setDescription(description);
+ }
+
+ if(dlg.exec() == QDialog::Accepted) {
+ Preset* preset = m_settings.newPreset(dlg.group(), dlg.description());
+ savePresetSettings(preset, ui->tabInputsView->currentIndex());
+
+ ui->presetTree->setCurrentItem(addPresetToTree(preset));
+ }
+}
+
+void MainWindow::on_presetUpdate_clicked()
+{
+ QTreeWidgetItem* item = ui->presetTree->currentItem();
+
+ if(item != 0) {
+ if(item->type() == PItem) {
+ const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
+ if (preset != 0) {
+ Preset* preset_mod = const_cast(preset);
+ savePresetSettings(preset_mod, ui->tabInputsView->currentIndex());
+ }
+ }
+ }
+}
+
+void MainWindow::on_presetExport_clicked()
+{
+ QTreeWidgetItem* item = ui->presetTree->currentItem();
+
+ if(item != 0) {
+ if(item->type() == PItem)
+ {
+ const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
+ QString base64Str = preset->serialize().toBase64();
+ QString fileName = QFileDialog::getSaveFileName(this,
+ tr("Open preset export file"), ".", tr("Preset export files (*.prex)"));
+
+ if (fileName != "")
+ {
+ QFileInfo fileInfo(fileName);
+
+ if (fileInfo.suffix() != "prex") {
+ fileName += ".prex";
+ }
+
+ QFile exportFile(fileName);
+
+ if (exportFile.open(QIODevice::WriteOnly | QIODevice::Text))
+ {
+ QTextStream outstream(&exportFile);
+ outstream << base64Str;
+ exportFile.close();
+ }
+ else
+ {
+ QMessageBox::information(this, tr("Message"), tr("Cannot open file for writing"));
+ }
+ }
+ }
+ }
+}
+
+void MainWindow::on_presetImport_clicked()
+{
+ QTreeWidgetItem* item = ui->presetTree->currentItem();
+
+ if(item != 0)
+ {
+ QString group;
+
+ if (item->type() == PGroup) {
+ group = item->text(0);
+ } else if (item->type() == PItem) {
+ group = item->parent()->text(0);
+ } else {
+ return;
+ }
+
+ QString fileName = QFileDialog::getOpenFileName(this,
+ tr("Open preset export file"), ".", tr("Preset export files (*.prex)"));
+
+ if (fileName != "")
+ {
+ QFile exportFile(fileName);
+
+ if (exportFile.open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ QByteArray base64Str;
+ QTextStream instream(&exportFile);
+ instream >> base64Str;
+ exportFile.close();
+
+ Preset* preset = m_settings.newPreset("", "");
+ preset->deserialize(QByteArray::fromBase64(base64Str));
+ preset->setGroup(group); // override with current group
+
+ ui->presetTree->setCurrentItem(addPresetToTree(preset));
+ }
+ else
+ {
+ QMessageBox::information(this, tr("Message"), tr("Cannot open file for reading"));
+ }
+ }
+ }
+}
+
+void MainWindow::on_settingsSave_clicked()
+{
+ savePresetSettings(m_settings.getWorkingPreset(), ui->tabInputsView->currentIndex());
+ m_settings.save();
+}
+
+void MainWindow::on_presetLoad_clicked()
+{
+ qDebug() << "MainWindow::on_presetLoad_clicked";
+
+ QTreeWidgetItem* item = ui->presetTree->currentItem();
+
+ if(item == 0)
+ {
+ qDebug("MainWindow::on_presetLoad_clicked: item null");
+ updatePresetControls();
+ return;
+ }
+
+ const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
+
+ if(preset == 0)
+ {
+ qDebug("MainWindow::on_presetLoad_clicked: preset null");
+ return;
+ }
+
+ loadPresetSettings(preset, ui->tabInputsView->currentIndex());
+ applySettings();
+}
+
+void MainWindow::on_presetDelete_clicked()
+{
+ QTreeWidgetItem* item = ui->presetTree->currentItem();
+ if(item == 0) {
+ updatePresetControls();
+ return;
+ }
+ const Preset* preset = qvariant_cast(item->data(0, Qt::UserRole));
+ if(preset == 0)
+ return;
+
+ if(QMessageBox::question(this, tr("Delete Preset"), tr("Do you want to delete preset '%1'?").arg(preset->getDescription()), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
+ delete item;
+ m_settings.deletePreset(preset);
+ }
+}
+
+void MainWindow::on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+{
+ updatePresetControls();
+}
+
+void MainWindow::on_presetTree_itemActivated(QTreeWidgetItem *item, int column)
+{
+ on_presetLoad_clicked();
+}
+
+void MainWindow::on_action_Loaded_Plugins_triggered()
+{
+ PluginsDialog pluginsDialog(m_pluginManager, this);
+ pluginsDialog.exec();
+}
+
+void MainWindow::on_action_Audio_triggered()
+{
+ AudioDialog audioDialog(&m_audioDeviceInfo, this);
+ audioDialog.exec();
+ m_dspEngine->setAudioInputVolume(m_audioDeviceInfo.getInputVolume());
+ m_dspEngine->setAudioInputDeviceIndex(m_audioDeviceInfo.getInputDeviceIndex());
+ m_dspEngine->setAudioOutputDeviceIndex(m_audioDeviceInfo.getOutputDeviceIndex());
+}
+
+void MainWindow::on_action_My_Position_triggered()
+{
+ MyPositionDialog myPositionDialog(m_settings, this);
+ myPositionDialog.exec();
+}
+
+void MainWindow::on_action_DV_Serial_triggered(bool checked)
+{
+ m_dspEngine->setDVSerialSupport(checked);
+
+ if (checked)
+ {
+ std::vector deviceNames;
+ m_dspEngine->getDVSerialNames(deviceNames);
+
+ if (deviceNames.size() == 0)
+ {
+ QMessageBox::information(this, tr("Message"), tr("No DV serial devices found"));
+ }
+ else
+ {
+ std::vector::iterator it = deviceNames.begin();
+ std::string deviceNamesStr = "DV Serial devices found: ";
+
+ while (it != deviceNames.end())
+ {
+ if (it != deviceNames.begin()) {
+ deviceNamesStr += ",";
+ }
+
+ deviceNamesStr += *it;
+ ++it;
+ }
+
+ QMessageBox::information(this, tr("Message"), tr(deviceNamesStr.c_str()));
+ }
+ }
+}
+
+void MainWindow::on_sampleSource_confirmClicked(bool checked)
+{
+ // Do it in the currently selected source tab
+ int currentSourceTabIndex = ui->tabInputsSelect->currentIndex();
+
+ if (currentSourceTabIndex >= 0)
+ {
+ qDebug("MainWindow::on_sampleSource_confirmClicked: tab at %d", currentSourceTabIndex);
+ DeviceUISet *deviceUI = m_deviceUIs[currentSourceTabIndex];
+ deviceUI->m_deviceSourceAPI->saveSourceSettings(m_settings.getWorkingPreset()); // save old API settings
+ int selectedComboIndex = deviceUI->m_samplingDeviceControl->getDeviceSelector()->currentIndex();
+ void *devicePtr = deviceUI->m_samplingDeviceControl->getDeviceSelector()->itemData(selectedComboIndex).value();
+ deviceUI->m_deviceSourceAPI->stopAcquisition();
+
+ // TODO: deviceUI->m_deviceSourceAPI->setSampleSourcePluginGUI(0); // deletes old GUI and input object
+ deviceUI->m_deviceSourceAPI->clearBuddiesLists(); // clear old API buddies lists
+
+ m_pluginManager->selectSampleSourceByDevice(devicePtr, deviceUI->m_deviceSourceAPI); // sets the new API
+
+ // TODO: move up add to buddies list
+
+ // TODO:
+// // constructs new GUI and input object
+// QWidget *gui;
+// PluginManager::SamplingDevice *sampleSourceDevice = (PluginManager::SamplingDevice *) devicePtr;
+// PluginGUI *pluginGUI = sampleSourceDevice->m_plugin->createSampleSourcePluginGUI(sampleSourceDevice->m_deviceId, &gui, deviceUI->m_deviceSourceAPI);
+//
+// deviceUI->m_deviceSourceAPI->setSampleSourcePluginGUI(pluginGUI);
+// deviceUI->m_deviceSourceAPI->setInputGUI(gui, sampleSourceDevice->m_displayName);
+
+ deviceUI->m_deviceSourceAPI->loadSourceSettings(m_settings.getWorkingPreset()); // load new API settings
+
+ // add to buddies list
+ std::vector::iterator it = m_deviceUIs.begin();
+ 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_deviceSourceAPI->getHardwareId() == (*it)->m_deviceSourceAPI->getHardwareId()) &&
+ (deviceUI->m_deviceSourceAPI->getSampleSourceSerial() == (*it)->m_deviceSourceAPI->getSampleSourceSerial()))
+ {
+ (*it)->m_deviceSourceAPI->addSourceBuddy(deviceUI->m_deviceSourceAPI);
+ }
+ }
+
+ if ((*it)->m_deviceSinkEngine) // it is a sink device
+ {
+ if ((deviceUI->m_deviceSourceAPI->getHardwareId() == (*it)->m_deviceSinkAPI->getHardwareId()) &&
+ (deviceUI->m_deviceSourceAPI->getSampleSourceSerial() == (*it)->m_deviceSinkAPI->getSampleSinkSerial()))
+ {
+ (*it)->m_deviceSinkAPI->addSourceBuddy(deviceUI->m_deviceSourceAPI);
+ }
+ }
+ }
+ }
+
+ if (currentSourceTabIndex == 0)
+ {
+ m_settings.setSourceIndex(deviceUI->m_samplingDeviceControl->getDeviceSelector()->currentIndex());
+ }
+ }
+}
+
+void MainWindow::on_sampleSink_confirmClicked(bool checked)
+{
+ // Do it in the currently selected source tab
+ int currentSinkTabIndex = ui->tabInputsSelect->currentIndex();
+
+ if (currentSinkTabIndex >= 0)
+ {
+ qDebug("MainWindow::on_sampleSink_confirmClicked: tab at %d", currentSinkTabIndex);
+ DeviceUISet *deviceUI = m_deviceUIs[currentSinkTabIndex];
+ deviceUI->m_deviceSinkAPI->saveSinkSettings(m_settings.getWorkingPreset()); // save old API settings
+ int selectedComboIndex = deviceUI->m_samplingDeviceControl->getDeviceSelector()->currentIndex();
+ void *devicePtr = deviceUI->m_samplingDeviceControl->getDeviceSelector()->itemData(selectedComboIndex).value();
+ deviceUI->m_deviceSinkAPI->stopGeneration();
+ deviceUI->m_deviceSinkAPI->clearBuddiesLists(); // remove old API from buddies lists
+ m_pluginManager->selectSampleSinkByDevice(devicePtr, deviceUI->m_deviceSinkAPI); // sets the new API
+ deviceUI->m_deviceSinkAPI->loadSinkSettings(m_settings.getWorkingPreset()); // load new API settings
+
+ // add to buddies list
+ std::vector::iterator it = m_deviceUIs.begin();
+ 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_deviceSinkAPI->getHardwareId() == (*it)->m_deviceSourceAPI->getHardwareId()) &&
+ (deviceUI->m_deviceSinkAPI->getSampleSinkSerial() == (*it)->m_deviceSourceAPI->getSampleSourceSerial()))
+ {
+ (*it)->m_deviceSourceAPI->addSinkBuddy(deviceUI->m_deviceSinkAPI);
+ }
+ }
+
+ if ((*it)->m_deviceSinkEngine) // it is a sink device
+ {
+ if ((deviceUI->m_deviceSinkAPI->getHardwareId() == (*it)->m_deviceSinkAPI->getHardwareId()) &&
+ (deviceUI->m_deviceSinkAPI->getSampleSinkSerial() == (*it)->m_deviceSinkAPI->getSampleSinkSerial()))
+ {
+ (*it)->m_deviceSinkAPI->addSinkBuddy(deviceUI->m_deviceSinkAPI);
+ }
+ }
+ }
+ }
+ }
+}
+
+void MainWindow::on_channel_addClicked(bool checked)
+{
+ // Do it in the currently selected source tab
+ int currentSourceTabIndex = ui->tabInputsSelect->currentIndex();
+
+ if (currentSourceTabIndex >= 0)
+ {
+ DeviceUISet *deviceUI = m_deviceUIs[currentSourceTabIndex];
+
+ if (deviceUI->m_deviceSourceEngine) // source device => Rx channels
+ {
+ m_pluginManager->createRxChannelInstance(deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI->m_deviceSourceAPI);
+ }
+ else if (deviceUI->m_deviceSinkEngine) // sink device => Tx channels
+ {
+ uint32_t nbSources = deviceUI->m_deviceSinkAPI->getNumberOfSources();
+
+ if (nbSources > 0) {
+ QMessageBox::information(this, tr("Message"), tr("%1 channel(s) already in use. Multiple transmission channels is experimental. You may experience performance problems").arg(nbSources));
+ }
+
+ m_pluginManager->createTxChannelInstance(deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI->m_deviceSinkAPI);
+ }
+ }
+
+}
+
+void MainWindow::on_action_About_triggered()
+{
+ AboutDialog dlg(this);
+ dlg.exec();
+}
+
+void MainWindow::on_action_addSourceDevice_triggered()
+{
+ addSourceDevice();
+}
+
+void MainWindow::on_action_addSinkDevice_triggered()
+{
+ addSinkDevice();
+}
+
+void MainWindow::on_action_removeLastDevice_triggered()
+{
+ if (m_deviceUIs.size() > 1)
+ {
+ removeLastDevice();
+ }
+}
+
+void MainWindow::on_action_reloadDevices_triggered()
+{
+ // all devices must be stopped
+ std::vector::iterator it = m_deviceUIs.begin();
+ for (; it != m_deviceUIs.end(); ++it)
+ {
+ if ((*it)->m_deviceSourceEngine) // it is a source device
+ {
+ if ((*it)->m_deviceSourceEngine->state() == DSPDeviceSourceEngine::StRunning)
+ {
+ QMessageBox::information(this, tr("Message"), tr("Stop all devices for reload to take effect"));
+ return;
+ }
+ }
+
+ if ((*it)->m_deviceSinkEngine) // it is a sink device
+ {
+ if ((*it)->m_deviceSinkEngine->state() == DSPDeviceSinkEngine::StRunning)
+ {
+ QMessageBox::information(this, tr("Message"), tr("Stop all devices for reload to take effect"));
+ return;
+ }
+ }
+ }
+
+ // re-scan devices
+ m_pluginManager->updateSampleSourceDevices();
+ m_pluginManager->updateSampleSinkDevices();
+
+ // re-populate device selectors keeping the same selection
+ it = m_deviceUIs.begin();
+ for (; it != m_deviceUIs.end(); ++it)
+ {
+ if ((*it)->m_deviceSourceEngine) // it is a source device
+ {
+ QComboBox *deviceSelectorComboBox = (*it)->m_samplingDeviceControl->getDeviceSelector();
+ bool sampleSourceSignalsBlocked = deviceSelectorComboBox->blockSignals(true);
+ m_pluginManager->fillSampleSourceSelector(deviceSelectorComboBox, (*it)->m_deviceSourceEngine->getUID());
+ int newIndex = m_pluginManager->getSampleSourceSelectorIndex(deviceSelectorComboBox, (*it)->m_deviceSourceAPI);
+ deviceSelectorComboBox->setCurrentIndex(newIndex);
+ deviceSelectorComboBox->blockSignals(sampleSourceSignalsBlocked);
+ }
+
+ if ((*it)->m_deviceSinkEngine) // it is a sink device
+ {
+ QComboBox *deviceSelectorComboBox = (*it)->m_samplingDeviceControl->getDeviceSelector();
+ bool sampleSinkSignalsBlocked = deviceSelectorComboBox->blockSignals(true);
+ m_pluginManager->fillSampleSinkSelector(deviceSelectorComboBox, (*it)->m_deviceSinkEngine->getUID());
+ int newIndex = m_pluginManager->getSampleSinkSelectorIndex(deviceSelectorComboBox, (*it)->m_deviceSinkAPI);
+ deviceSelectorComboBox->setCurrentIndex(newIndex);
+ deviceSelectorComboBox->blockSignals(sampleSinkSignalsBlocked);
+ }
+ }
+}
+
+void MainWindow::on_action_Exit_triggered()
+{
+ savePresetSettings(m_settings.getWorkingPreset(), 0);
+ m_settings.save();
+
+ while (m_deviceUIs.size() > 0)
+ {
+ removeLastDevice();
+ }
+}
+
+void MainWindow::tabInputViewIndexChanged()
+{
+ int inputViewIndex = ui->tabInputsView->currentIndex();
+
+ if ((inputViewIndex >= 0) && (m_masterTabIndex >= 0) && (inputViewIndex != m_masterTabIndex))
+ {
+ DeviceUISet *deviceUI = m_deviceUIs[inputViewIndex];
+ DeviceUISet *lastdeviceUI = m_deviceUIs[m_masterTabIndex];
+ lastdeviceUI->m_mainWindowState = saveState();
+ restoreState(deviceUI->m_mainWindowState);
+ m_masterTabIndex = inputViewIndex;
+ }
+
+ ui->tabSpectra->setCurrentIndex(inputViewIndex);
+ ui->tabChannels->setCurrentIndex(inputViewIndex);
+ ui->tabInputsSelect->setCurrentIndex(inputViewIndex);
+ ui->tabSpectraGUI->setCurrentIndex(inputViewIndex);
+}
+
+void MainWindow::updateStatus()
+{
+ m_dateTimeWidget->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss t"));
+}
+
+MainWindow::DeviceUISet::DeviceUISet(QTimer& timer)
+{
+ m_spectrum = new GLSpectrum;
+ m_spectrumVis = new SpectrumVis(m_spectrum);
+ m_spectrum->connectTimer(timer);
+ m_spectrumGUI = new GLSpectrumGUI;
+ m_spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, m_spectrum);
+ m_channelWindow = new ChannelWindow;
+ m_samplingDeviceControl = new SamplingDeviceControl;
+ m_deviceSourceEngine = 0;
+ m_deviceSourceAPI = 0;
+ m_deviceSinkEngine = 0;
+ m_deviceSinkAPI = 0;
+
+ // m_spectrum needs to have its font to be set since it cannot be inherited from the main window
+ QFont font;
+ font.setFamily(QStringLiteral("Sans Serif"));
+ font.setPointSize(9);
+ m_spectrum->setFont(font);
+
+}
+
+MainWindow::DeviceUISet::~DeviceUISet()
+{
+ delete m_samplingDeviceControl;
+ delete m_channelWindow;
+ delete m_spectrumGUI;
+ delete m_spectrumVis;
+ delete m_spectrum;
+}
diff --git a/sdrbase/plugin/pluginmanager.cpp b/sdrbase/plugin/pluginmanager.cpp
index 2b407c577..82753217d 100644
--- a/sdrbase/plugin/pluginmanager.cpp
+++ b/sdrbase/plugin/pluginmanager.cpp
@@ -1,815 +1,819 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2016 Edouard Griffiths, F4EXB //
-// //
-// 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 //
-// //
-// 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 "device/devicesourceapi.h"
-#include "device/devicesinkapi.h"
-#include
-#include
-#include
-#include
-
-#include "plugin/pluginmanager.h"
-#include "plugin/plugingui.h"
-#include "settings/preset.h"
-#include "mainwindow.h"
-#include "gui/glspectrum.h"
-#include "util/message.h"
-
-#include
-#include "dsp/dspdevicesourceengine.h"
-#include "dsp/dspdevicesinkengine.h"
-
-const QString PluginManager::m_sdrDaemonHardwareID = "SDRdaemon";
-const QString PluginManager::m_sdrDaemonDeviceTypeID = "sdrangel.samplesource.sdrdaemon";
-const QString PluginManager::m_sdrDaemonFECHardwareID = "SDRdaemonFEC";
-const QString PluginManager::m_sdrDaemonFECDeviceTypeID = "sdrangel.samplesource.sdrdaemonfec";
-const QString PluginManager::m_fileSourceHardwareID = "FileSource";
-const QString PluginManager::m_fileSourceDeviceTypeID = "sdrangel.samplesource.filesource";
-const QString PluginManager::m_fileSinkDeviceTypeID = "sdrangel.samplesink.filesink";
-
-PluginManager::PluginManager(MainWindow* mainWindow, QObject* parent) :
- QObject(parent),
- m_pluginAPI(this, mainWindow),
- m_mainWindow(mainWindow)
-{
-}
-
-PluginManager::~PluginManager()
-{
-// freeAll();
-}
-
-void PluginManager::loadPlugins()
-{
- QString applicationDirPath = QApplication::instance()->applicationDirPath();
- QString applicationLibPath = applicationDirPath + "/../lib";
- qDebug() << "PluginManager::loadPlugins: " << qPrintable(applicationDirPath) << ", " << qPrintable(applicationLibPath);
-
- QDir pluginsBinDir = QDir(applicationDirPath);
- QDir pluginsLibDir = QDir(applicationLibPath);
-
- loadPlugins(pluginsBinDir);
- loadPlugins(pluginsLibDir);
-
- qSort(m_plugins);
-
- for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
- {
- it->pluginInterface->initPlugin(&m_pluginAPI);
- }
-
- updateSampleSourceDevices();
- updateSampleSinkDevices();
-}
-
-void PluginManager::registerRxChannel(const QString& channelName, PluginInterface* plugin)
-{
- qDebug() << "PluginManager::registerRxChannel "
- << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
- << " with channel name " << channelName;
-
- m_rxChannelRegistrations.append(PluginAPI::ChannelRegistration(channelName, plugin));
-}
-
-void PluginManager::registerTxChannel(const QString& channelName, PluginInterface* plugin)
-{
- qDebug() << "PluginManager::registerTxChannel "
- << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
- << " with channel name " << channelName;
-
- m_txChannelRegistrations.append(PluginAPI::ChannelRegistration(channelName, plugin));
-}
-
-void PluginManager::registerSampleSource(const QString& sourceName, PluginInterface* plugin)
-{
- qDebug() << "PluginManager::registerSampleSource "
- << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
- << " with source name " << sourceName.toStdString().c_str();
-
- m_sampleSourceRegistrations.append(SamplingDeviceRegistration(sourceName, plugin));
-}
-
-void PluginManager::registerSampleSink(const QString& sinkName, PluginInterface* plugin)
-{
- qDebug() << "PluginManager::registerSampleSink "
- << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
- << " with sink name " << sinkName.toStdString().c_str();
-
- m_sampleSinkRegistrations.append(SamplingDeviceRegistration(sinkName, plugin));
-}
-
-void PluginManager::updateSampleSourceDevices()
-{
- m_sampleSourceDevices.clear();
-
- for(int i = 0; i < m_sampleSourceRegistrations.count(); ++i)
- {
- PluginInterface::SamplingDevices ssd = m_sampleSourceRegistrations[i].m_plugin->enumSampleSources();
-
- for(int j = 0; j < ssd.count(); ++j)
- {
- m_sampleSourceDevices.append(SamplingDevice(m_sampleSourceRegistrations[i].m_plugin,
- ssd[j].displayedName,
- ssd[j].hardwareId,
- ssd[j].id,
- ssd[j].serial,
- ssd[j].sequence));
- }
- }
-}
-
-void PluginManager::updateSampleSinkDevices()
-{
- m_sampleSinkDevices.clear();
-
- for(int i = 0; i < m_sampleSinkRegistrations.count(); ++i)
- {
- PluginInterface::SamplingDevices ssd = m_sampleSinkRegistrations[i].m_plugin->enumSampleSinks();
-
- for(int j = 0; j < ssd.count(); ++j)
- {
- m_sampleSinkDevices.append(SamplingDevice(m_sampleSinkRegistrations[i].m_plugin,
- ssd[j].displayedName,
- ssd[j].hardwareId,
- ssd[j].id,
- ssd[j].serial,
- ssd[j].sequence));
- }
- }
-}
-
-void PluginManager::duplicateLocalSampleSourceDevices(uint deviceUID)
-{
- if (deviceUID == 0) {
- return;
- }
-
- SamplingDevice *sdrDaemonSSD0 = 0;
- SamplingDevice *sdrDaemonFECSSD0 = 0;
- SamplingDevice *fileSourceSSD0 = 0;
- bool duplicateSDRDaemon = true;
- bool duplicateSDRDaemonFEC = true;
- bool duplicateFileSource = true;
-
- for(int i = 0; i < m_sampleSourceDevices.count(); ++i)
- {
- if (m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonDeviceTypeID) // SDRdaemon
- {
- if (m_sampleSourceDevices[i].m_deviceSequence == 0) { // reference to device 0
- sdrDaemonSSD0 = &m_sampleSourceDevices[i];
- }
- else if (m_sampleSourceDevices[i].m_deviceSequence == deviceUID) { // already there
- duplicateSDRDaemon = false;
- }
- }
- else if (m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonFECDeviceTypeID) // SDRdaemon with FEC
- {
- if (m_sampleSourceDevices[i].m_deviceSequence == 0) { // reference to device 0
- sdrDaemonFECSSD0 = &m_sampleSourceDevices[i];
- }
- else if (m_sampleSourceDevices[i].m_deviceSequence == deviceUID) { // already there
- duplicateSDRDaemonFEC = false;
- }
- }
- else if (m_sampleSourceDevices[i].m_deviceId == m_fileSourceDeviceTypeID) // File Source
- {
- if (m_sampleSourceDevices[i].m_deviceSequence == 0) { // reference to device 0
- fileSourceSSD0 = &m_sampleSourceDevices[i];
- }
- else if (m_sampleSourceDevices[i].m_deviceSequence == deviceUID) { // already there
- duplicateFileSource = false;
- }
- }
- }
-
- if (sdrDaemonSSD0 && duplicateSDRDaemon) // append item for a new instance
- {
- m_sampleSourceDevices.append(
- SamplingDevice(
- sdrDaemonSSD0->m_plugin,
- QString("SDRdaemon[%1]").arg(deviceUID),
- sdrDaemonSSD0->m_hadrwareId,
- sdrDaemonSSD0->m_deviceId,
- sdrDaemonSSD0->m_deviceSerial,
- deviceUID
- )
- );
- }
-
- if (sdrDaemonFECSSD0 && duplicateSDRDaemonFEC) // append item for a new instance
- {
- m_sampleSourceDevices.append(
- SamplingDevice(
- sdrDaemonFECSSD0->m_plugin,
- QString("SDRdaemonFEC[%1]").arg(deviceUID),
- sdrDaemonFECSSD0->m_hadrwareId,
- sdrDaemonFECSSD0->m_deviceId,
- sdrDaemonFECSSD0->m_deviceSerial,
- deviceUID
- )
- );
- }
-
- if (fileSourceSSD0 && duplicateFileSource) // append item for a new instance
- {
- m_sampleSourceDevices.append(
- SamplingDevice(
- fileSourceSSD0->m_plugin,
- QString("FileSource[%1]").arg(deviceUID),
- fileSourceSSD0->m_hadrwareId,
- fileSourceSSD0->m_deviceId,
- fileSourceSSD0->m_deviceSerial,
- deviceUID
- )
- );
- }
-}
-
-void PluginManager::duplicateLocalSampleSinkDevices(uint deviceUID)
-{
- if (deviceUID == 0) {
- return;
- }
-
- SamplingDevice *fileSinkSSD0 = 0;
- bool duplicateFileSink = true;
-
- for(int i = 0; i < m_sampleSinkDevices.count(); ++i)
- {
- if (m_sampleSinkDevices[i].m_deviceId == m_fileSinkDeviceTypeID) // File Sink
- {
- if (m_sampleSinkDevices[i].m_deviceSequence == 0) { // reference to device 0
- fileSinkSSD0 = &m_sampleSinkDevices[i];
- }
- else if (m_sampleSinkDevices[i].m_deviceSequence == deviceUID) { // already there
- duplicateFileSink = false;
- }
- }
- }
-
- if (fileSinkSSD0 && duplicateFileSink) // append item for a new instance
- {
- m_sampleSinkDevices.append(
- SamplingDevice(
- fileSinkSSD0->m_plugin,
- QString("FileSink[%1]").arg(deviceUID),
- fileSinkSSD0->m_hadrwareId,
- fileSinkSSD0->m_deviceId,
- fileSinkSSD0->m_deviceSerial,
- deviceUID
- )
- );
- }
-}
-
-void PluginManager::fillSampleSourceSelector(QComboBox* comboBox, uint deviceUID)
-{
- comboBox->clear();
-
- for(int i = 0; i < m_sampleSourceDevices.count(); i++)
- {
- // For "local" devices show only ones that concern this device set
- if ((m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonDeviceTypeID)
- || (m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonFECDeviceTypeID)
- || (m_sampleSourceDevices[i].m_deviceId == m_fileSourceDeviceTypeID))
- {
- if (deviceUID != m_sampleSourceDevices[i].m_deviceSequence) {
- continue;
- }
- }
-
- comboBox->addItem(m_sampleSourceDevices[i].m_displayName, qVariantFromValue((void *) &m_sampleSourceDevices[i]));
- }
-}
-
-int PluginManager::getSampleSourceSelectorIndex(QComboBox* comboBox, DeviceSourceAPI *deviceSourceAPI)
-{
- for (int i = 0; i < comboBox->count(); i++)
- {
- SamplingDevice *samplingDevice = (SamplingDevice*) (comboBox->itemData(i)).value();
-
- if ((samplingDevice->m_deviceId == deviceSourceAPI->getSampleSourceId()) &&
- (samplingDevice->m_deviceSerial == deviceSourceAPI->getSampleSourceSerial()) &&
- (samplingDevice->m_deviceSequence == deviceSourceAPI->getSampleSourceSequence()))
- {
- return i;
- }
- }
-
- return 0; // default to first item
-}
-
-void PluginManager::fillSampleSinkSelector(QComboBox* comboBox, uint deviceUID)
-{
- comboBox->clear();
-
- for(int i = 0; i < m_sampleSinkDevices.count(); i++)
- {
- // For "local" devices show only ones that concern this device set
- if (m_sampleSinkDevices[i].m_deviceId == m_fileSinkDeviceTypeID)
- {
- if (deviceUID != m_sampleSinkDevices[i].m_deviceSequence) {
- continue;
- }
- }
-
- comboBox->addItem(m_sampleSinkDevices[i].m_displayName, qVariantFromValue((void *) &m_sampleSinkDevices[i]));
- }
-}
-
-int PluginManager::getSampleSinkSelectorIndex(QComboBox* comboBox, DeviceSinkAPI *deviceSinkAPI)
-{
- for (int i = 0; i < comboBox->count(); i++)
- {
- SamplingDevice *samplingDevice = (SamplingDevice*) (comboBox->itemData(i)).value();
-
- if ((samplingDevice->m_deviceId == deviceSinkAPI->getSampleSinkId()) &&
- (samplingDevice->m_deviceSerial == deviceSinkAPI->getSampleSinkSerial()) &&
- (samplingDevice->m_deviceSequence == deviceSinkAPI->getSampleSinkSequence()))
- {
- return i;
- }
- }
-
- return 0; // default to first item
-}
-
-int PluginManager::selectSampleSourceByIndex(int index, DeviceSourceAPI *deviceAPI)
-{
- qDebug("PluginManager::selectSampleSourceByIndex: index: %d", index);
-
- if (m_sampleSourceDevices.count() == 0)
- {
- return -1;
- }
-
- if (index < 0)
- {
- return -1;
- }
-
- if (index >= m_sampleSourceDevices.count())
- {
- index = 0;
- }
-
- qDebug() << "PluginManager::selectSampleSourceByIndex: m_sampleSource at index " << index
- << " hid: " << m_sampleSourceDevices[index].m_hadrwareId.toStdString().c_str()
- << " id: " << m_sampleSourceDevices[index].m_deviceId.toStdString().c_str()
- << " ser: " << m_sampleSourceDevices[index].m_deviceSerial.toStdString().c_str()
- << " seq: " << m_sampleSourceDevices[index].m_deviceSequence;
-
- deviceAPI->stopAcquisition();
- deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = m_sampleSourceDevices[index].m_plugin->createSampleSourcePluginGUI(m_sampleSourceDevices[index].m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSourceSequence(m_sampleSourceDevices[index].m_deviceSequence);
- deviceAPI->setHardwareId(m_sampleSourceDevices[index].m_hadrwareId);
- deviceAPI->setSampleSourceId(m_sampleSourceDevices[index].m_deviceId);
- deviceAPI->setSampleSourceSerial(m_sampleSourceDevices[index].m_deviceSerial);
- deviceAPI->setSampleSourcePluginGUI(pluginGUI);
- deviceAPI->setInputGUI(gui, m_sampleSourceDevices[index].m_displayName);
-
- return index;
-}
-
-int PluginManager::selectSampleSinkByIndex(int index, DeviceSinkAPI *deviceAPI)
-{
- qDebug("PluginManager::selectSampleSinkByIndex: index: %d", index);
-
- if (m_sampleSinkDevices.count() == 0)
- {
- return -1;
- }
-
- if (index < 0)
- {
- return -1;
- }
-
- if (index >= m_sampleSinkDevices.count())
- {
- index = 0;
- }
-
- qDebug() << "PluginManager::selectSampleSinkByIndex: m_sampleSink at index " << index
- << " hid: " << m_sampleSinkDevices[index].m_hadrwareId.toStdString().c_str()
- << " id: " << m_sampleSinkDevices[index].m_deviceId.toStdString().c_str()
- << " ser: " << m_sampleSinkDevices[index].m_deviceSerial.toStdString().c_str()
- << " seq: " << m_sampleSinkDevices[index].m_deviceSequence;
-
- deviceAPI->stopGeneration();
- deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = m_sampleSinkDevices[index].m_plugin->createSampleSinkPluginGUI(m_sampleSinkDevices[index].m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSinkSequence(m_sampleSinkDevices[index].m_deviceSequence);
- deviceAPI->setHardwareId(m_sampleSinkDevices[index].m_hadrwareId);
- deviceAPI->setSampleSinkId(m_sampleSinkDevices[index].m_deviceId);
- deviceAPI->setSampleSinkSerial(m_sampleSinkDevices[index].m_deviceSerial);
- deviceAPI->setSampleSinkPluginGUI(pluginGUI);
- deviceAPI->setOutputGUI(gui, m_sampleSinkDevices[index].m_displayName);
-
- return index;
-}
-
-int PluginManager::selectFirstSampleSource(const QString& sourceId, DeviceSourceAPI *deviceAPI)
-{
- qDebug("PluginManager::selectFirstSampleSource by id: [%s]", qPrintable(sourceId));
-
- int index = -1;
-
- for (int i = 0; i < m_sampleSourceDevices.count(); i++)
- {
- qDebug("*** %s vs %s", qPrintable(m_sampleSourceDevices[i].m_deviceId), qPrintable(sourceId));
-
- if(m_sampleSourceDevices[i].m_deviceId == sourceId)
- {
- index = i;
- break;
- }
- }
-
- if(index == -1)
- {
- if(m_sampleSourceDevices.count() > 0)
- {
- index = 0;
- }
- else
- {
- return -1;
- }
- }
-
- qDebug() << "PluginManager::selectFirstSampleSource: m_sampleSource at index " << index
- << " hid: " << m_sampleSourceDevices[index].m_hadrwareId.toStdString().c_str()
- << " id: " << m_sampleSourceDevices[index].m_deviceId.toStdString().c_str()
- << " ser: " << m_sampleSourceDevices[index].m_deviceSerial.toStdString().c_str()
- << " seq: " << m_sampleSourceDevices[index].m_deviceSequence;
-
- deviceAPI->stopAcquisition();
- deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = m_sampleSourceDevices[index].m_plugin->createSampleSourcePluginGUI(m_sampleSourceDevices[index].m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSourceSequence(m_sampleSourceDevices[index].m_deviceSequence);
- deviceAPI->setHardwareId(m_sampleSourceDevices[index].m_hadrwareId);
- deviceAPI->setSampleSourceId(m_sampleSourceDevices[index].m_deviceId);
- deviceAPI->setSampleSourceSerial(m_sampleSourceDevices[index].m_deviceSerial);
- deviceAPI->setSampleSourcePluginGUI(pluginGUI);
- deviceAPI->setInputGUI(gui, m_sampleSourceDevices[index].m_displayName);
-
- return index;
-}
-
-int PluginManager::selectFirstSampleSink(const QString& sinkId, DeviceSinkAPI *deviceAPI)
-{
- qDebug("PluginManager::selectFirstSampleSink by id: [%s]", qPrintable(sinkId));
-
- int index = -1;
-
- for (int i = 0; i < m_sampleSinkDevices.count(); i++)
- {
- qDebug("*** %s vs %s", qPrintable(m_sampleSinkDevices[i].m_deviceId), qPrintable(sinkId));
-
- if(m_sampleSinkDevices[i].m_deviceId == sinkId)
- {
- index = i;
- break;
- }
- }
-
- if(index == -1)
- {
- if(m_sampleSinkDevices.count() > 0)
- {
- index = 0;
- }
- else
- {
- return -1;
- }
- }
-
- qDebug() << "PluginManager::selectFirstSampleSink: m_sampleSink at index " << index
- << " hid: " << m_sampleSinkDevices[index].m_hadrwareId.toStdString().c_str()
- << " id: " << m_sampleSinkDevices[index].m_deviceId.toStdString().c_str()
- << " ser: " << m_sampleSinkDevices[index].m_deviceSerial.toStdString().c_str()
- << " seq: " << m_sampleSinkDevices[index].m_deviceSequence;
-
- deviceAPI->stopGeneration();
- deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = m_sampleSinkDevices[index].m_plugin->createSampleSinkPluginGUI(m_sampleSinkDevices[index].m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSinkSequence(m_sampleSinkDevices[index].m_deviceSequence);
- deviceAPI->setHardwareId(m_sampleSinkDevices[index].m_hadrwareId);
- deviceAPI->setSampleSinkId(m_sampleSinkDevices[index].m_deviceId);
- deviceAPI->setSampleSinkSerial(m_sampleSinkDevices[index].m_deviceSerial);
- deviceAPI->setSampleSinkPluginGUI(pluginGUI);
- deviceAPI->setOutputGUI(gui, m_sampleSinkDevices[index].m_displayName);
-
- return index;
-}
-
-int PluginManager::selectSampleSourceBySerialOrSequence(const QString& sourceId, const QString& sourceSerial, int sourceSequence, DeviceSourceAPI *deviceAPI)
-{
- qDebug("PluginManager::selectSampleSourceBySequence by sequence: id: %s ser: %s seq: %d", qPrintable(sourceId), qPrintable(sourceSerial), sourceSequence);
-
- int index = -1;
- int index_matchingSequence = -1;
- int index_firstOfKind = -1;
-
- for (int i = 0; i < m_sampleSourceDevices.count(); i++)
- {
- if (m_sampleSourceDevices[i].m_deviceId == sourceId)
- {
- index_firstOfKind = i;
-
- if (m_sampleSourceDevices[i].m_deviceSerial == sourceSerial)
- {
- index = i; // exact match
- break;
- }
-
- if (m_sampleSourceDevices[i].m_deviceSequence == sourceSequence)
- {
- index_matchingSequence = i;
- }
- }
- }
-
- if(index == -1) // no exact match
- {
- if (index_matchingSequence == -1) // no matching sequence
- {
- if (index_firstOfKind == -1) // no matching device type
- {
- if(m_sampleSourceDevices.count() > 0) // take first if any
- {
- index = 0;
- }
- else
- {
- return -1; // return if no device attached
- }
- }
- else
- {
- index = index_firstOfKind; // take first that matches device type
- }
- }
- else
- {
- index = index_matchingSequence; // take the one that matches the sequence in the device type
- }
- }
-
- qDebug() << "PluginManager::selectSampleSourceBySequence: m_sampleSource at index " << index
- << " hid: " << m_sampleSourceDevices[index].m_hadrwareId.toStdString().c_str()
- << " id: " << m_sampleSourceDevices[index].m_deviceId.toStdString().c_str()
- << " ser: " << m_sampleSourceDevices[index].m_deviceSerial.toStdString().c_str()
- << " seq: " << m_sampleSourceDevices[index].m_deviceSequence;
-
- deviceAPI->stopAcquisition();
- deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = m_sampleSourceDevices[index].m_plugin->createSampleSourcePluginGUI(m_sampleSourceDevices[index].m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSourceSequence(m_sampleSourceDevices[index].m_deviceSequence);
- deviceAPI->setHardwareId(m_sampleSourceDevices[index].m_hadrwareId);
- deviceAPI->setSampleSourceId(m_sampleSourceDevices[index].m_deviceId);
- deviceAPI->setSampleSourceSerial(m_sampleSourceDevices[index].m_deviceSerial);
- deviceAPI->setSampleSourcePluginGUI(pluginGUI);
- deviceAPI->setInputGUI(gui, m_sampleSourceDevices[index].m_displayName);
-
- return index;
-}
-
-int PluginManager::selectSampleSinkBySerialOrSequence(const QString& sinkId, const QString& sinkSerial, int sinkSequence, DeviceSinkAPI *deviceAPI)
-{
- qDebug("PluginManager::selectSampleSinkBySerialOrSequence by sequence: id: %s ser: %s seq: %d", qPrintable(sinkId), qPrintable(sinkSerial), sinkSequence);
-
- int index = -1;
- int index_matchingSequence = -1;
- int index_firstOfKind = -1;
-
- for (int i = 0; i < m_sampleSinkDevices.count(); i++)
- {
- if (m_sampleSinkDevices[i].m_deviceId == sinkId)
- {
- index_firstOfKind = i;
-
- if (m_sampleSinkDevices[i].m_deviceSerial == sinkSerial)
- {
- index = i; // exact match
- break;
- }
-
- if (m_sampleSinkDevices[i].m_deviceSequence == sinkSequence)
- {
- index_matchingSequence = i;
- }
- }
- }
-
- if(index == -1) // no exact match
- {
- if (index_matchingSequence == -1) // no matching sequence
- {
- if (index_firstOfKind == -1) // no matching device type
- {
- if(m_sampleSinkDevices.count() > 0) // take first if any
- {
- index = 0;
- }
- else
- {
- return -1; // return if no device attached
- }
- }
- else
- {
- index = index_firstOfKind; // take first that matches device type
- }
- }
- else
- {
- index = index_matchingSequence; // take the one that matches the sequence in the device type
- }
- }
-
- qDebug() << "PluginManager::selectSampleSinkBySerialOrSequence: m_sampleSink at index " << index
- << " hid: " << m_sampleSinkDevices[index].m_hadrwareId.toStdString().c_str()
- << " id: " << m_sampleSinkDevices[index].m_deviceId.toStdString().c_str()
- << " ser: " << m_sampleSinkDevices[index].m_deviceSerial.toStdString().c_str()
- << " seq: " << m_sampleSinkDevices[index].m_deviceSequence;
-
- deviceAPI->stopGeneration();
- deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = m_sampleSinkDevices[index].m_plugin->createSampleSinkPluginGUI(m_sampleSinkDevices[index].m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSinkSequence(m_sampleSinkDevices[index].m_deviceSequence);
- deviceAPI->setHardwareId(m_sampleSinkDevices[index].m_hadrwareId);
- deviceAPI->setSampleSinkId(m_sampleSinkDevices[index].m_deviceId);
- deviceAPI->setSampleSinkSerial(m_sampleSinkDevices[index].m_deviceSerial);
- deviceAPI->setSampleSinkPluginGUI(pluginGUI);
- deviceAPI->setOutputGUI(gui, m_sampleSinkDevices[index].m_displayName);
-
- return index;
-}
-
-void PluginManager::selectSampleSourceByDevice(void *devicePtr, DeviceSourceAPI *deviceAPI)
-{
- SamplingDevice *sampleSourceDevice = (SamplingDevice *) devicePtr;
-
- qDebug() << "PluginManager::selectSampleSourceByDevice: "
- << " hid: " << sampleSourceDevice->m_hadrwareId.toStdString().c_str()
- << " id: " << sampleSourceDevice->m_deviceId.toStdString().c_str()
- << " ser: " << sampleSourceDevice->m_deviceSerial.toStdString().c_str()
- << " seq: " << sampleSourceDevice->m_deviceSequence;
-
- deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = sampleSourceDevice->m_plugin->createSampleSourcePluginGUI(sampleSourceDevice->m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSourceSequence(sampleSourceDevice->m_deviceSequence);
- deviceAPI->setHardwareId(sampleSourceDevice->m_hadrwareId);
- deviceAPI->setSampleSourceId(sampleSourceDevice->m_deviceId);
- deviceAPI->setSampleSourceSerial(sampleSourceDevice->m_deviceSerial);
- deviceAPI->setSampleSourcePluginGUI(pluginGUI);
- deviceAPI->setInputGUI(gui, sampleSourceDevice->m_displayName);
-}
-
-void PluginManager::selectSampleSinkByDevice(void *devicePtr, DeviceSinkAPI *deviceAPI)
-{
- SamplingDevice *sampleSinkDevice = (SamplingDevice *) devicePtr;
-
- qDebug() << "PluginManager::selectSampleSinkByDevice: "
- << " hid: " << sampleSinkDevice->m_hadrwareId.toStdString().c_str()
- << " id: " << sampleSinkDevice->m_deviceId.toStdString().c_str()
- << " ser: " << sampleSinkDevice->m_deviceSerial.toStdString().c_str()
- << " seq: " << sampleSinkDevice->m_deviceSequence;
-
- deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
-
- QWidget *gui;
- PluginGUI *pluginGUI = sampleSinkDevice->m_plugin->createSampleSinkPluginGUI(sampleSinkDevice->m_deviceId, &gui, deviceAPI);
-
- // m_sampleSourcePluginGUI = pluginGUI;
- deviceAPI->setSampleSinkSequence(sampleSinkDevice->m_deviceSequence);
- deviceAPI->setHardwareId(sampleSinkDevice->m_hadrwareId);
- deviceAPI->setSampleSinkId(sampleSinkDevice->m_deviceId);
- deviceAPI->setSampleSinkSerial(sampleSinkDevice->m_deviceSerial);
- deviceAPI->setSampleSinkPluginGUI(pluginGUI);
- deviceAPI->setOutputGUI(gui, sampleSinkDevice->m_displayName);
-}
-
-void PluginManager::loadPlugins(const QDir& dir)
-{
- QDir pluginsDir(dir);
-
- foreach (QString fileName, pluginsDir.entryList(QDir::Files))
- {
- if (fileName.endsWith(".so") || fileName.endsWith(".dll") || fileName.endsWith(".dylib"))
- {
- qDebug() << "PluginManager::loadPlugins: fileName: " << qPrintable(fileName);
-
- QPluginLoader* loader = new QPluginLoader(pluginsDir.absoluteFilePath(fileName));
- PluginInterface* plugin = qobject_cast(loader->instance());
-
- if (loader->isLoaded())
- {
- qWarning("PluginManager::loadPlugins: loaded plugin %s", qPrintable(fileName));
- }
- else
- {
- qWarning() << "PluginManager::loadPlugins: " << qPrintable(loader->errorString());
- }
-
- if (plugin != 0)
- {
- m_plugins.append(Plugin(fileName, loader, plugin));
- }
- else
- {
- loader->unload();
- }
-
- delete loader; // Valgrind memcheck
- }
- }
-
- // recursive calls on subdirectories
-
- foreach (QString dirName, pluginsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
- {
- loadPlugins(pluginsDir.absoluteFilePath(dirName));
- }
-}
-
-void PluginManager::populateRxChannelComboBox(QComboBox *channels)
-{
- for(PluginAPI::ChannelRegistrations::iterator it = m_rxChannelRegistrations.begin(); it != m_rxChannelRegistrations.end(); ++it)
- {
- const PluginDescriptor& pluginDescipror = it->m_plugin->getPluginDescriptor();
- channels->addItem(pluginDescipror.displayedName);
- }
-}
-
-void PluginManager::populateTxChannelComboBox(QComboBox *channels)
-{
- for(PluginAPI::ChannelRegistrations::iterator it = m_txChannelRegistrations.begin(); it != m_txChannelRegistrations.end(); ++it)
- {
- const PluginDescriptor& pluginDescipror = it->m_plugin->getPluginDescriptor();
- channels->addItem(pluginDescipror.displayedName);
- }
-}
-
-void PluginManager::createRxChannelInstance(int channelPluginIndex, DeviceSourceAPI *deviceAPI)
-{
- if (channelPluginIndex < m_rxChannelRegistrations.size())
- {
- PluginInterface *pluginInterface = m_rxChannelRegistrations[channelPluginIndex].m_plugin;
- pluginInterface->createRxChannel(m_rxChannelRegistrations[channelPluginIndex].m_channelName, deviceAPI);
- }
-}
-
-void PluginManager::createTxChannelInstance(int channelPluginIndex, DeviceSinkAPI *deviceAPI)
-{
- if (channelPluginIndex < m_txChannelRegistrations.size())
- {
- PluginInterface *pluginInterface = m_txChannelRegistrations[channelPluginIndex].m_plugin;
- pluginInterface->createTxChannel(m_txChannelRegistrations[channelPluginIndex].m_channelName, deviceAPI);
- }
-}
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2016 Edouard Griffiths, F4EXB //
+// //
+// 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 //
+// //
+// 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 "device/devicesourceapi.h"
+#include "device/devicesinkapi.h"
+#include
+#include
+#include
+#include
+
+#include "plugin/pluginmanager.h"
+#include "plugin/plugingui.h"
+#include "settings/preset.h"
+#include "mainwindow.h"
+#include "gui/glspectrum.h"
+#include "util/message.h"
+
+#include
+#include "dsp/dspdevicesourceengine.h"
+#include "dsp/dspdevicesinkengine.h"
+
+const QString PluginManager::m_sdrDaemonHardwareID = "SDRdaemon";
+const QString PluginManager::m_sdrDaemonDeviceTypeID = "sdrangel.samplesource.sdrdaemon";
+const QString PluginManager::m_sdrDaemonFECHardwareID = "SDRdaemonFEC";
+const QString PluginManager::m_sdrDaemonFECDeviceTypeID = "sdrangel.samplesource.sdrdaemonfec";
+const QString PluginManager::m_fileSourceHardwareID = "FileSource";
+const QString PluginManager::m_fileSourceDeviceTypeID = "sdrangel.samplesource.filesource";
+const QString PluginManager::m_fileSinkDeviceTypeID = "sdrangel.samplesink.filesink";
+
+PluginManager::PluginManager(MainWindow* mainWindow, QObject* parent) :
+ QObject(parent),
+ m_pluginAPI(this, mainWindow),
+ m_mainWindow(mainWindow)
+{
+}
+
+PluginManager::~PluginManager()
+{
+// freeAll();
+}
+
+void PluginManager::loadPlugins()
+{
+ QString applicationDirPath = QApplication::instance()->applicationDirPath();
+ QString applicationLibPath = applicationDirPath + "/../lib";
+ qDebug() << "PluginManager::loadPlugins: " << qPrintable(applicationDirPath) << ", " << qPrintable(applicationLibPath);
+
+ QDir pluginsBinDir = QDir(applicationDirPath);
+ QDir pluginsLibDir = QDir(applicationLibPath);
+
+ loadPlugins(pluginsBinDir);
+ loadPlugins(pluginsLibDir);
+
+ qSort(m_plugins);
+
+ for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
+ {
+ it->pluginInterface->initPlugin(&m_pluginAPI);
+ }
+
+ updateSampleSourceDevices();
+ updateSampleSinkDevices();
+}
+
+void PluginManager::registerRxChannel(const QString& channelName, PluginInterface* plugin)
+{
+ qDebug() << "PluginManager::registerRxChannel "
+ << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
+ << " with channel name " << channelName;
+
+ m_rxChannelRegistrations.append(PluginAPI::ChannelRegistration(channelName, plugin));
+}
+
+void PluginManager::registerTxChannel(const QString& channelName, PluginInterface* plugin)
+{
+ qDebug() << "PluginManager::registerTxChannel "
+ << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
+ << " with channel name " << channelName;
+
+ m_txChannelRegistrations.append(PluginAPI::ChannelRegistration(channelName, plugin));
+}
+
+void PluginManager::registerSampleSource(const QString& sourceName, PluginInterface* plugin)
+{
+ qDebug() << "PluginManager::registerSampleSource "
+ << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
+ << " with source name " << sourceName.toStdString().c_str();
+
+ m_sampleSourceRegistrations.append(SamplingDeviceRegistration(sourceName, plugin));
+}
+
+void PluginManager::registerSampleSink(const QString& sinkName, PluginInterface* plugin)
+{
+ qDebug() << "PluginManager::registerSampleSink "
+ << plugin->getPluginDescriptor().displayedName.toStdString().c_str()
+ << " with sink name " << sinkName.toStdString().c_str();
+
+ m_sampleSinkRegistrations.append(SamplingDeviceRegistration(sinkName, plugin));
+}
+
+void PluginManager::updateSampleSourceDevices()
+{
+ m_sampleSourceDevices.clear();
+
+ for(int i = 0; i < m_sampleSourceRegistrations.count(); ++i)
+ {
+ PluginInterface::SamplingDevices ssd = m_sampleSourceRegistrations[i].m_plugin->enumSampleSources();
+
+ for(int j = 0; j < ssd.count(); ++j)
+ {
+ m_sampleSourceDevices.append(SamplingDevice(m_sampleSourceRegistrations[i].m_plugin,
+ ssd[j].displayedName,
+ ssd[j].hardwareId,
+ ssd[j].id,
+ ssd[j].serial,
+ ssd[j].sequence));
+ }
+ }
+}
+
+void PluginManager::updateSampleSinkDevices()
+{
+ m_sampleSinkDevices.clear();
+
+ for(int i = 0; i < m_sampleSinkRegistrations.count(); ++i)
+ {
+ PluginInterface::SamplingDevices ssd = m_sampleSinkRegistrations[i].m_plugin->enumSampleSinks();
+
+ for(int j = 0; j < ssd.count(); ++j)
+ {
+ m_sampleSinkDevices.append(SamplingDevice(m_sampleSinkRegistrations[i].m_plugin,
+ ssd[j].displayedName,
+ ssd[j].hardwareId,
+ ssd[j].id,
+ ssd[j].serial,
+ ssd[j].sequence));
+ }
+ }
+}
+
+void PluginManager::duplicateLocalSampleSourceDevices(uint deviceUID)
+{
+ if (deviceUID == 0) {
+ return;
+ }
+
+ SamplingDevice *sdrDaemonSSD0 = 0;
+ SamplingDevice *sdrDaemonFECSSD0 = 0;
+ SamplingDevice *fileSourceSSD0 = 0;
+ bool duplicateSDRDaemon = true;
+ bool duplicateSDRDaemonFEC = true;
+ bool duplicateFileSource = true;
+
+ for(int i = 0; i < m_sampleSourceDevices.count(); ++i)
+ {
+ if (m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonDeviceTypeID) // SDRdaemon
+ {
+ if (m_sampleSourceDevices[i].m_deviceSequence == 0) { // reference to device 0
+ sdrDaemonSSD0 = &m_sampleSourceDevices[i];
+ }
+ else if (m_sampleSourceDevices[i].m_deviceSequence == deviceUID) { // already there
+ duplicateSDRDaemon = false;
+ }
+ }
+ else if (m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonFECDeviceTypeID) // SDRdaemon with FEC
+ {
+ if (m_sampleSourceDevices[i].m_deviceSequence == 0) { // reference to device 0
+ sdrDaemonFECSSD0 = &m_sampleSourceDevices[i];
+ }
+ else if (m_sampleSourceDevices[i].m_deviceSequence == deviceUID) { // already there
+ duplicateSDRDaemonFEC = false;
+ }
+ }
+ else if (m_sampleSourceDevices[i].m_deviceId == m_fileSourceDeviceTypeID) // File Source
+ {
+ if (m_sampleSourceDevices[i].m_deviceSequence == 0) { // reference to device 0
+ fileSourceSSD0 = &m_sampleSourceDevices[i];
+ }
+ else if (m_sampleSourceDevices[i].m_deviceSequence == deviceUID) { // already there
+ duplicateFileSource = false;
+ }
+ }
+ }
+
+ if (sdrDaemonSSD0 && duplicateSDRDaemon) // append item for a new instance
+ {
+ m_sampleSourceDevices.append(
+ SamplingDevice(
+ sdrDaemonSSD0->m_plugin,
+ QString("SDRdaemon[%1]").arg(deviceUID),
+ sdrDaemonSSD0->m_hadrwareId,
+ sdrDaemonSSD0->m_deviceId,
+ sdrDaemonSSD0->m_deviceSerial,
+ deviceUID
+ )
+ );
+ }
+
+ if (sdrDaemonFECSSD0 && duplicateSDRDaemonFEC) // append item for a new instance
+ {
+ m_sampleSourceDevices.append(
+ SamplingDevice(
+ sdrDaemonFECSSD0->m_plugin,
+ QString("SDRdaemonFEC[%1]").arg(deviceUID),
+ sdrDaemonFECSSD0->m_hadrwareId,
+ sdrDaemonFECSSD0->m_deviceId,
+ sdrDaemonFECSSD0->m_deviceSerial,
+ deviceUID
+ )
+ );
+ }
+
+ if (fileSourceSSD0 && duplicateFileSource) // append item for a new instance
+ {
+ m_sampleSourceDevices.append(
+ SamplingDevice(
+ fileSourceSSD0->m_plugin,
+ QString("FileSource[%1]").arg(deviceUID),
+ fileSourceSSD0->m_hadrwareId,
+ fileSourceSSD0->m_deviceId,
+ fileSourceSSD0->m_deviceSerial,
+ deviceUID
+ )
+ );
+ }
+}
+
+void PluginManager::duplicateLocalSampleSinkDevices(uint deviceUID)
+{
+ if (deviceUID == 0) {
+ return;
+ }
+
+ SamplingDevice *fileSinkSSD0 = 0;
+ bool duplicateFileSink = true;
+
+ for(int i = 0; i < m_sampleSinkDevices.count(); ++i)
+ {
+ if (m_sampleSinkDevices[i].m_deviceId == m_fileSinkDeviceTypeID) // File Sink
+ {
+ if (m_sampleSinkDevices[i].m_deviceSequence == 0) { // reference to device 0
+ fileSinkSSD0 = &m_sampleSinkDevices[i];
+ }
+ else if (m_sampleSinkDevices[i].m_deviceSequence == deviceUID) { // already there
+ duplicateFileSink = false;
+ }
+ }
+ }
+
+ if (fileSinkSSD0 && duplicateFileSink) // append item for a new instance
+ {
+ m_sampleSinkDevices.append(
+ SamplingDevice(
+ fileSinkSSD0->m_plugin,
+ QString("FileSink[%1]").arg(deviceUID),
+ fileSinkSSD0->m_hadrwareId,
+ fileSinkSSD0->m_deviceId,
+ fileSinkSSD0->m_deviceSerial,
+ deviceUID
+ )
+ );
+ }
+}
+
+void PluginManager::fillSampleSourceSelector(QComboBox* comboBox, uint deviceUID)
+{
+ comboBox->clear();
+
+ for(int i = 0; i < m_sampleSourceDevices.count(); i++)
+ {
+ // For "local" devices show only ones that concern this device set
+ if ((m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonDeviceTypeID)
+ || (m_sampleSourceDevices[i].m_deviceId == m_sdrDaemonFECDeviceTypeID)
+ || (m_sampleSourceDevices[i].m_deviceId == m_fileSourceDeviceTypeID))
+ {
+ if (deviceUID != m_sampleSourceDevices[i].m_deviceSequence) {
+ continue;
+ }
+ }
+
+ comboBox->addItem(m_sampleSourceDevices[i].m_displayName, qVariantFromValue((void *) &m_sampleSourceDevices[i]));
+ }
+}
+
+int PluginManager::getSampleSourceSelectorIndex(QComboBox* comboBox, DeviceSourceAPI *deviceSourceAPI)
+{
+ for (int i = 0; i < comboBox->count(); i++)
+ {
+ SamplingDevice *samplingDevice = (SamplingDevice*) (comboBox->itemData(i)).value();
+
+ if ((samplingDevice->m_deviceId == deviceSourceAPI->getSampleSourceId()) &&
+ (samplingDevice->m_deviceSerial == deviceSourceAPI->getSampleSourceSerial()) &&
+ (samplingDevice->m_deviceSequence == deviceSourceAPI->getSampleSourceSequence()))
+ {
+ return i;
+ }
+ }
+
+ return 0; // default to first item
+}
+
+void PluginManager::fillSampleSinkSelector(QComboBox* comboBox, uint deviceUID)
+{
+ comboBox->clear();
+
+ for(int i = 0; i < m_sampleSinkDevices.count(); i++)
+ {
+ // For "local" devices show only ones that concern this device set
+ if (m_sampleSinkDevices[i].m_deviceId == m_fileSinkDeviceTypeID)
+ {
+ if (deviceUID != m_sampleSinkDevices[i].m_deviceSequence) {
+ continue;
+ }
+ }
+
+ comboBox->addItem(m_sampleSinkDevices[i].m_displayName, qVariantFromValue((void *) &m_sampleSinkDevices[i]));
+ }
+}
+
+int PluginManager::getSampleSinkSelectorIndex(QComboBox* comboBox, DeviceSinkAPI *deviceSinkAPI)
+{
+ for (int i = 0; i < comboBox->count(); i++)
+ {
+ SamplingDevice *samplingDevice = (SamplingDevice*) (comboBox->itemData(i)).value();
+
+ if ((samplingDevice->m_deviceId == deviceSinkAPI->getSampleSinkId()) &&
+ (samplingDevice->m_deviceSerial == deviceSinkAPI->getSampleSinkSerial()) &&
+ (samplingDevice->m_deviceSequence == deviceSinkAPI->getSampleSinkSequence()))
+ {
+ return i;
+ }
+ }
+
+ return 0; // default to first item
+}
+
+int PluginManager::selectSampleSourceByIndex(int index, DeviceSourceAPI *deviceAPI)
+{
+ qDebug("PluginManager::selectSampleSourceByIndex: index: %d", index);
+
+ if (m_sampleSourceDevices.count() == 0)
+ {
+ return -1;
+ }
+
+ if (index < 0)
+ {
+ return -1;
+ }
+
+ if (index >= m_sampleSourceDevices.count())
+ {
+ index = 0;
+ }
+
+ qDebug() << "PluginManager::selectSampleSourceByIndex: m_sampleSource at index " << index
+ << " hid: " << m_sampleSourceDevices[index].m_hadrwareId.toStdString().c_str()
+ << " id: " << m_sampleSourceDevices[index].m_deviceId.toStdString().c_str()
+ << " ser: " << m_sampleSourceDevices[index].m_deviceSerial.toStdString().c_str()
+ << " seq: " << m_sampleSourceDevices[index].m_deviceSequence;
+
+ deviceAPI->stopAcquisition();
+ deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = m_sampleSourceDevices[index].m_plugin->createSampleSourcePluginGUI(m_sampleSourceDevices[index].m_deviceId, &gui, deviceAPI);
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSourceSequence(m_sampleSourceDevices[index].m_deviceSequence);
+ deviceAPI->setHardwareId(m_sampleSourceDevices[index].m_hadrwareId);
+ deviceAPI->setSampleSourceId(m_sampleSourceDevices[index].m_deviceId);
+ deviceAPI->setSampleSourceSerial(m_sampleSourceDevices[index].m_deviceSerial);
+ deviceAPI->setSampleSourcePluginGUI(pluginGUI);
+ deviceAPI->setInputGUI(gui, m_sampleSourceDevices[index].m_displayName);
+
+ return index;
+}
+
+int PluginManager::selectSampleSinkByIndex(int index, DeviceSinkAPI *deviceAPI)
+{
+ qDebug("PluginManager::selectSampleSinkByIndex: index: %d", index);
+
+ if (m_sampleSinkDevices.count() == 0)
+ {
+ return -1;
+ }
+
+ if (index < 0)
+ {
+ return -1;
+ }
+
+ if (index >= m_sampleSinkDevices.count())
+ {
+ index = 0;
+ }
+
+ qDebug() << "PluginManager::selectSampleSinkByIndex: m_sampleSink at index " << index
+ << " hid: " << m_sampleSinkDevices[index].m_hadrwareId.toStdString().c_str()
+ << " id: " << m_sampleSinkDevices[index].m_deviceId.toStdString().c_str()
+ << " ser: " << m_sampleSinkDevices[index].m_deviceSerial.toStdString().c_str()
+ << " seq: " << m_sampleSinkDevices[index].m_deviceSequence;
+
+ deviceAPI->stopGeneration();
+ deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = m_sampleSinkDevices[index].m_plugin->createSampleSinkPluginGUI(m_sampleSinkDevices[index].m_deviceId, &gui, deviceAPI);
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSinkSequence(m_sampleSinkDevices[index].m_deviceSequence);
+ deviceAPI->setHardwareId(m_sampleSinkDevices[index].m_hadrwareId);
+ deviceAPI->setSampleSinkId(m_sampleSinkDevices[index].m_deviceId);
+ deviceAPI->setSampleSinkSerial(m_sampleSinkDevices[index].m_deviceSerial);
+ deviceAPI->setSampleSinkPluginGUI(pluginGUI);
+ deviceAPI->setOutputGUI(gui, m_sampleSinkDevices[index].m_displayName);
+
+ return index;
+}
+
+int PluginManager::selectFirstSampleSource(const QString& sourceId, DeviceSourceAPI *deviceAPI)
+{
+ qDebug("PluginManager::selectFirstSampleSource by id: [%s]", qPrintable(sourceId));
+
+ int index = -1;
+
+ for (int i = 0; i < m_sampleSourceDevices.count(); i++)
+ {
+ qDebug("*** %s vs %s", qPrintable(m_sampleSourceDevices[i].m_deviceId), qPrintable(sourceId));
+
+ if(m_sampleSourceDevices[i].m_deviceId == sourceId)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ if(index == -1)
+ {
+ if(m_sampleSourceDevices.count() > 0)
+ {
+ index = 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ qDebug() << "PluginManager::selectFirstSampleSource: m_sampleSource at index " << index
+ << " hid: " << m_sampleSourceDevices[index].m_hadrwareId.toStdString().c_str()
+ << " id: " << m_sampleSourceDevices[index].m_deviceId.toStdString().c_str()
+ << " ser: " << m_sampleSourceDevices[index].m_deviceSerial.toStdString().c_str()
+ << " seq: " << m_sampleSourceDevices[index].m_deviceSequence;
+
+ deviceAPI->stopAcquisition();
+ deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = m_sampleSourceDevices[index].m_plugin->createSampleSourcePluginGUI(m_sampleSourceDevices[index].m_deviceId, &gui, deviceAPI);
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSourceSequence(m_sampleSourceDevices[index].m_deviceSequence);
+ deviceAPI->setHardwareId(m_sampleSourceDevices[index].m_hadrwareId);
+ deviceAPI->setSampleSourceId(m_sampleSourceDevices[index].m_deviceId);
+ deviceAPI->setSampleSourceSerial(m_sampleSourceDevices[index].m_deviceSerial);
+ deviceAPI->setSampleSourcePluginGUI(pluginGUI);
+ deviceAPI->setInputGUI(gui, m_sampleSourceDevices[index].m_displayName);
+
+ return index;
+}
+
+int PluginManager::selectFirstSampleSink(const QString& sinkId, DeviceSinkAPI *deviceAPI)
+{
+ qDebug("PluginManager::selectFirstSampleSink by id: [%s]", qPrintable(sinkId));
+
+ int index = -1;
+
+ for (int i = 0; i < m_sampleSinkDevices.count(); i++)
+ {
+ qDebug("*** %s vs %s", qPrintable(m_sampleSinkDevices[i].m_deviceId), qPrintable(sinkId));
+
+ if(m_sampleSinkDevices[i].m_deviceId == sinkId)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ if(index == -1)
+ {
+ if(m_sampleSinkDevices.count() > 0)
+ {
+ index = 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ qDebug() << "PluginManager::selectFirstSampleSink: m_sampleSink at index " << index
+ << " hid: " << m_sampleSinkDevices[index].m_hadrwareId.toStdString().c_str()
+ << " id: " << m_sampleSinkDevices[index].m_deviceId.toStdString().c_str()
+ << " ser: " << m_sampleSinkDevices[index].m_deviceSerial.toStdString().c_str()
+ << " seq: " << m_sampleSinkDevices[index].m_deviceSequence;
+
+ deviceAPI->stopGeneration();
+ deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = m_sampleSinkDevices[index].m_plugin->createSampleSinkPluginGUI(m_sampleSinkDevices[index].m_deviceId, &gui, deviceAPI);
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSinkSequence(m_sampleSinkDevices[index].m_deviceSequence);
+ deviceAPI->setHardwareId(m_sampleSinkDevices[index].m_hadrwareId);
+ deviceAPI->setSampleSinkId(m_sampleSinkDevices[index].m_deviceId);
+ deviceAPI->setSampleSinkSerial(m_sampleSinkDevices[index].m_deviceSerial);
+ deviceAPI->setSampleSinkPluginGUI(pluginGUI);
+ deviceAPI->setOutputGUI(gui, m_sampleSinkDevices[index].m_displayName);
+
+ return index;
+}
+
+int PluginManager::selectSampleSourceBySerialOrSequence(const QString& sourceId, const QString& sourceSerial, int sourceSequence, DeviceSourceAPI *deviceAPI)
+{
+ qDebug("PluginManager::selectSampleSourceBySequence by sequence: id: %s ser: %s seq: %d", qPrintable(sourceId), qPrintable(sourceSerial), sourceSequence);
+
+ int index = -1;
+ int index_matchingSequence = -1;
+ int index_firstOfKind = -1;
+
+ for (int i = 0; i < m_sampleSourceDevices.count(); i++)
+ {
+ if (m_sampleSourceDevices[i].m_deviceId == sourceId)
+ {
+ index_firstOfKind = i;
+
+ if (m_sampleSourceDevices[i].m_deviceSerial == sourceSerial)
+ {
+ index = i; // exact match
+ break;
+ }
+
+ if (m_sampleSourceDevices[i].m_deviceSequence == sourceSequence)
+ {
+ index_matchingSequence = i;
+ }
+ }
+ }
+
+ if(index == -1) // no exact match
+ {
+ if (index_matchingSequence == -1) // no matching sequence
+ {
+ if (index_firstOfKind == -1) // no matching device type
+ {
+ if(m_sampleSourceDevices.count() > 0) // take first if any
+ {
+ index = 0;
+ }
+ else
+ {
+ return -1; // return if no device attached
+ }
+ }
+ else
+ {
+ index = index_firstOfKind; // take first that matches device type
+ }
+ }
+ else
+ {
+ index = index_matchingSequence; // take the one that matches the sequence in the device type
+ }
+ }
+
+ qDebug() << "PluginManager::selectSampleSourceBySequence: m_sampleSource at index " << index
+ << " hid: " << m_sampleSourceDevices[index].m_hadrwareId.toStdString().c_str()
+ << " id: " << m_sampleSourceDevices[index].m_deviceId.toStdString().c_str()
+ << " ser: " << m_sampleSourceDevices[index].m_deviceSerial.toStdString().c_str()
+ << " seq: " << m_sampleSourceDevices[index].m_deviceSequence;
+
+ deviceAPI->stopAcquisition();
+ deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = m_sampleSourceDevices[index].m_plugin->createSampleSourcePluginGUI(m_sampleSourceDevices[index].m_deviceId, &gui, deviceAPI);
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSourceSequence(m_sampleSourceDevices[index].m_deviceSequence);
+ deviceAPI->setHardwareId(m_sampleSourceDevices[index].m_hadrwareId);
+ deviceAPI->setSampleSourceId(m_sampleSourceDevices[index].m_deviceId);
+ deviceAPI->setSampleSourceSerial(m_sampleSourceDevices[index].m_deviceSerial);
+ deviceAPI->setSampleSourcePluginGUI(pluginGUI);
+ deviceAPI->setInputGUI(gui, m_sampleSourceDevices[index].m_displayName);
+
+ return index;
+}
+
+int PluginManager::selectSampleSinkBySerialOrSequence(const QString& sinkId, const QString& sinkSerial, int sinkSequence, DeviceSinkAPI *deviceAPI)
+{
+ qDebug("PluginManager::selectSampleSinkBySerialOrSequence by sequence: id: %s ser: %s seq: %d", qPrintable(sinkId), qPrintable(sinkSerial), sinkSequence);
+
+ int index = -1;
+ int index_matchingSequence = -1;
+ int index_firstOfKind = -1;
+
+ for (int i = 0; i < m_sampleSinkDevices.count(); i++)
+ {
+ if (m_sampleSinkDevices[i].m_deviceId == sinkId)
+ {
+ index_firstOfKind = i;
+
+ if (m_sampleSinkDevices[i].m_deviceSerial == sinkSerial)
+ {
+ index = i; // exact match
+ break;
+ }
+
+ if (m_sampleSinkDevices[i].m_deviceSequence == sinkSequence)
+ {
+ index_matchingSequence = i;
+ }
+ }
+ }
+
+ if(index == -1) // no exact match
+ {
+ if (index_matchingSequence == -1) // no matching sequence
+ {
+ if (index_firstOfKind == -1) // no matching device type
+ {
+ if(m_sampleSinkDevices.count() > 0) // take first if any
+ {
+ index = 0;
+ }
+ else
+ {
+ return -1; // return if no device attached
+ }
+ }
+ else
+ {
+ index = index_firstOfKind; // take first that matches device type
+ }
+ }
+ else
+ {
+ index = index_matchingSequence; // take the one that matches the sequence in the device type
+ }
+ }
+
+ qDebug() << "PluginManager::selectSampleSinkBySerialOrSequence: m_sampleSink at index " << index
+ << " hid: " << m_sampleSinkDevices[index].m_hadrwareId.toStdString().c_str()
+ << " id: " << m_sampleSinkDevices[index].m_deviceId.toStdString().c_str()
+ << " ser: " << m_sampleSinkDevices[index].m_deviceSerial.toStdString().c_str()
+ << " seq: " << m_sampleSinkDevices[index].m_deviceSequence;
+
+ deviceAPI->stopGeneration();
+ deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = m_sampleSinkDevices[index].m_plugin->createSampleSinkPluginGUI(m_sampleSinkDevices[index].m_deviceId, &gui, deviceAPI);
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSinkSequence(m_sampleSinkDevices[index].m_deviceSequence);
+ deviceAPI->setHardwareId(m_sampleSinkDevices[index].m_hadrwareId);
+ deviceAPI->setSampleSinkId(m_sampleSinkDevices[index].m_deviceId);
+ deviceAPI->setSampleSinkSerial(m_sampleSinkDevices[index].m_deviceSerial);
+ deviceAPI->setSampleSinkPluginGUI(pluginGUI);
+ deviceAPI->setOutputGUI(gui, m_sampleSinkDevices[index].m_displayName);
+
+ return index;
+}
+
+void PluginManager::selectSampleSourceByDevice(void *devicePtr, DeviceSourceAPI *deviceAPI)
+{
+ SamplingDevice *sampleSourceDevice = (SamplingDevice *) devicePtr;
+
+ qDebug() << "PluginManager::selectSampleSourceByDevice: "
+ << " hid: " << sampleSourceDevice->m_hadrwareId.toStdString().c_str()
+ << " id: " << sampleSourceDevice->m_deviceId.toStdString().c_str()
+ << " ser: " << sampleSourceDevice->m_deviceSerial.toStdString().c_str()
+ << " seq: " << sampleSourceDevice->m_deviceSequence;
+
+ deviceAPI->setSampleSourcePluginGUI(0); // this effectively destroys the previous GUI if it exists // TODO: move out
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSourceSequence(sampleSourceDevice->m_deviceSequence);
+ deviceAPI->setHardwareId(sampleSourceDevice->m_hadrwareId);
+ deviceAPI->setSampleSourceId(sampleSourceDevice->m_deviceId);
+ deviceAPI->setSampleSourceSerial(sampleSourceDevice->m_deviceSerial);
+
+ // TOOD: move out the rest
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = sampleSourceDevice->m_plugin->createSampleSourcePluginGUI(sampleSourceDevice->m_deviceId, &gui, deviceAPI);
+
+ deviceAPI->setSampleSourcePluginGUI(pluginGUI);
+ deviceAPI->setInputGUI(gui, sampleSourceDevice->m_displayName);
+}
+
+void PluginManager::selectSampleSinkByDevice(void *devicePtr, DeviceSinkAPI *deviceAPI)
+{
+ SamplingDevice *sampleSinkDevice = (SamplingDevice *) devicePtr;
+
+ qDebug() << "PluginManager::selectSampleSinkByDevice: "
+ << " hid: " << sampleSinkDevice->m_hadrwareId.toStdString().c_str()
+ << " id: " << sampleSinkDevice->m_deviceId.toStdString().c_str()
+ << " ser: " << sampleSinkDevice->m_deviceSerial.toStdString().c_str()
+ << " seq: " << sampleSinkDevice->m_deviceSequence;
+
+ deviceAPI->setSampleSinkPluginGUI(0); // this effectively destroys the previous GUI if it exists
+
+ // m_sampleSourcePluginGUI = pluginGUI;
+ deviceAPI->setSampleSinkSequence(sampleSinkDevice->m_deviceSequence);
+ deviceAPI->setHardwareId(sampleSinkDevice->m_hadrwareId);
+ deviceAPI->setSampleSinkId(sampleSinkDevice->m_deviceId);
+ deviceAPI->setSampleSinkSerial(sampleSinkDevice->m_deviceSerial);
+
+ QWidget *gui;
+ PluginGUI *pluginGUI = sampleSinkDevice->m_plugin->createSampleSinkPluginGUI(sampleSinkDevice->m_deviceId, &gui, deviceAPI);
+
+ deviceAPI->setSampleSinkPluginGUI(pluginGUI);
+ deviceAPI->setOutputGUI(gui, sampleSinkDevice->m_displayName);
+}
+
+void PluginManager::loadPlugins(const QDir& dir)
+{
+ QDir pluginsDir(dir);
+
+ foreach (QString fileName, pluginsDir.entryList(QDir::Files))
+ {
+ if (fileName.endsWith(".so") || fileName.endsWith(".dll") || fileName.endsWith(".dylib"))
+ {
+ qDebug() << "PluginManager::loadPlugins: fileName: " << qPrintable(fileName);
+
+ QPluginLoader* loader = new QPluginLoader(pluginsDir.absoluteFilePath(fileName));
+ PluginInterface* plugin = qobject_cast(loader->instance());
+
+ if (loader->isLoaded())
+ {
+ qWarning("PluginManager::loadPlugins: loaded plugin %s", qPrintable(fileName));
+ }
+ else
+ {
+ qWarning() << "PluginManager::loadPlugins: " << qPrintable(loader->errorString());
+ }
+
+ if (plugin != 0)
+ {
+ m_plugins.append(Plugin(fileName, loader, plugin));
+ }
+ else
+ {
+ loader->unload();
+ }
+
+ delete loader; // Valgrind memcheck
+ }
+ }
+
+ // recursive calls on subdirectories
+
+ foreach (QString dirName, pluginsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
+ {
+ loadPlugins(pluginsDir.absoluteFilePath(dirName));
+ }
+}
+
+void PluginManager::populateRxChannelComboBox(QComboBox *channels)
+{
+ for(PluginAPI::ChannelRegistrations::iterator it = m_rxChannelRegistrations.begin(); it != m_rxChannelRegistrations.end(); ++it)
+ {
+ const PluginDescriptor& pluginDescipror = it->m_plugin->getPluginDescriptor();
+ channels->addItem(pluginDescipror.displayedName);
+ }
+}
+
+void PluginManager::populateTxChannelComboBox(QComboBox *channels)
+{
+ for(PluginAPI::ChannelRegistrations::iterator it = m_txChannelRegistrations.begin(); it != m_txChannelRegistrations.end(); ++it)
+ {
+ const PluginDescriptor& pluginDescipror = it->m_plugin->getPluginDescriptor();
+ channels->addItem(pluginDescipror.displayedName);
+ }
+}
+
+void PluginManager::createRxChannelInstance(int channelPluginIndex, DeviceSourceAPI *deviceAPI)
+{
+ if (channelPluginIndex < m_rxChannelRegistrations.size())
+ {
+ PluginInterface *pluginInterface = m_rxChannelRegistrations[channelPluginIndex].m_plugin;
+ pluginInterface->createRxChannel(m_rxChannelRegistrations[channelPluginIndex].m_channelName, deviceAPI);
+ }
+}
+
+void PluginManager::createTxChannelInstance(int channelPluginIndex, DeviceSinkAPI *deviceAPI)
+{
+ if (channelPluginIndex < m_txChannelRegistrations.size())
+ {
+ PluginInterface *pluginInterface = m_txChannelRegistrations[channelPluginIndex].m_plugin;
+ pluginInterface->createTxChannel(m_txChannelRegistrations[channelPluginIndex].m_channelName, deviceAPI);
+ }
+}