diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt
index 3f3507065..d5a6324aa 100644
--- a/sdrgui/CMakeLists.txt
+++ b/sdrgui/CMakeLists.txt
@@ -14,6 +14,8 @@ set(sdrgui_SOURCES
gui/basicchannelsettingsdialog.cpp
gui/basicdevicesettingsdialog.cpp
gui/buttonswitch.cpp
+ gui/channeladddialog.cpp
+ gui/channelsdock.cpp
gui/channelwindow.cpp
gui/clickablelabel.cpp
gui/colormapper.cpp
@@ -86,6 +88,8 @@ set(sdrgui_HEADERS
gui/basicchannelsettingsdialog.h
gui/basicdevicesettingsdialog.h
gui/buttonswitch.h
+ gui/channeladddialog.h
+ gui/channelsdock.h
gui/channelwindow.h
gui/colormapper.h
gui/commanditem.h
@@ -154,6 +158,7 @@ set(sdrgui_FORMS
gui/ambedevicesdialog.ui
gui/basicchannelsettingsdialog.ui
gui/basicdevicesettingsdialog.ui
+ gui/channeladddialog.ui
gui/commandoutputdialog.ui
gui/cwkeyergui.ui
gui/devicestreamselectiondialog.ui
diff --git a/sdrgui/gui/channeladddialog.cpp b/sdrgui/gui/channeladddialog.cpp
new file mode 100644
index 000000000..a9b7138ac
--- /dev/null
+++ b/sdrgui/gui/channeladddialog.cpp
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2020 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+
+#include "channeladddialog.h"
+#include "ui_channeladddialog.h"
+
+ChannelAddDialog::ChannelAddDialog(QWidget* parent) :
+ QDialog(parent),
+ ui(new Ui::ChannelAddDialog)
+{
+ ui->setupUi(this);
+ connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(apply(QAbstractButton*)));
+}
+
+ChannelAddDialog::~ChannelAddDialog()
+{
+ delete ui;
+}
+
+void ChannelAddDialog::resetChannelNames()
+{
+ ui->channelSelect->clear();
+}
+
+void ChannelAddDialog::addChannelNames(const QStringList& channelNames)
+{
+ ui->channelSelect->addItems(channelNames);
+}
+
+void ChannelAddDialog::apply(QAbstractButton *button)
+{
+ if (button == (QAbstractButton*) ui->buttonBox->button(QDialogButtonBox::Apply))
+ {
+ int selectedChannelIndex = ui->channelSelect->currentIndex();
+ emit(addChannel(selectedChannelIndex));
+ }
+}
diff --git a/sdrgui/gui/channeladddialog.h b/sdrgui/gui/channeladddialog.h
new file mode 100644
index 000000000..6959f1bbe
--- /dev/null
+++ b/sdrgui/gui/channeladddialog.h
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2020 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SDRGUI_GUI_CHANNELADDDIALOG_H_
+#define SDRGUI_GUI_CHANNELADDDIALOG_H_
+
+#include
+#include
+
+#include "export.h"
+
+class QStringList;
+class QAbstractButton;
+
+namespace Ui {
+ class ChannelAddDialog;
+}
+
+class SDRGUI_API ChannelAddDialog : public QDialog {
+ Q_OBJECT
+public:
+ explicit ChannelAddDialog(QWidget* parent = nullptr);
+ ~ChannelAddDialog();
+
+ void resetChannelNames();
+ void addChannelNames(const QStringList& channelNames);
+
+private:
+ Ui::ChannelAddDialog* ui;
+ std::vector m_channelIndexes;
+
+private slots:
+ void apply(QAbstractButton*);
+
+signals:
+ void addChannel(int);
+};
+
+#endif /* SDRGUI_GUI_CHANNELADDDIALOG_H_ */
diff --git a/sdrgui/gui/channeladddialog.ui b/sdrgui/gui/channeladddialog.ui
new file mode 100644
index 000000000..392acd9e0
--- /dev/null
+++ b/sdrgui/gui/channeladddialog.ui
@@ -0,0 +1,110 @@
+
+
+ ChannelAddDialog
+
+
+
+ 0
+ 0
+ 324
+ 139
+
+
+
+
+ Liberation Sans
+ 9
+
+
+
+ Add Channels
+
+
+ -
+
+
+
+ 16777215
+ 70
+
+
+
+
+ Liberation Sans
+ 9
+
+
+
+ Available channels
+
+
+
-
+
+
+
+ Liberation Sans
+ 9
+
+
+
+
+
+
+
+ -
+
+
+
+ Liberation Sans
+ 9
+
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Apply|QDialogButtonBox::Close
+
+
+
+
+
+
+ buttonBox
+
+
+
+
+ buttonBox
+ accepted()
+ ChannelAddDialog
+ accept()
+
+
+ 257
+ 194
+
+
+ 157
+ 203
+
+
+
+
+ buttonBox
+ rejected()
+ ChannelAddDialog
+ reject()
+
+
+ 314
+ 194
+
+
+ 286
+ 203
+
+
+
+
+
diff --git a/sdrgui/gui/channelsdock.cpp b/sdrgui/gui/channelsdock.cpp
new file mode 100644
index 000000000..9cab1ed3f
--- /dev/null
+++ b/sdrgui/gui/channelsdock.cpp
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2020 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+
+#include "channelsdock.h"
+
+ChannelsDock::ChannelsDock(QWidget *parent, Qt::WindowFlags flags) :
+ QDockWidget(parent, flags),
+ m_channelAddDialog(this)
+{
+ m_titleBar = new QWidget();
+ m_titleBarLayout = new QHBoxLayout();
+ m_titleBarLayout->setMargin(0);
+ m_titleBar->setLayout(m_titleBarLayout);
+
+ m_titleLabel = new QLabel();
+ m_titleLabel->setText(QString("Channels"));
+
+ m_addChannelButton = new QPushButton();
+ QIcon addIcon(":/create.png");
+ m_addChannelButton->setIcon(addIcon);
+ m_addChannelButton->setToolTip("Add channels");
+ m_addChannelButton->setFixedSize(16, 16);
+
+ m_normalButton = new QPushButton();
+ QIcon normalIcon = style()->standardIcon(QStyle::SP_TitleBarNormalButton, 0, this);
+ m_normalButton->setIcon(normalIcon);
+ m_normalButton->setFixedSize(12, 12);
+
+ m_closeButton = new QPushButton();
+ QIcon closeIcon = style()->standardIcon(QStyle::SP_TitleBarCloseButton, 0, this);
+ m_closeButton->setIcon(closeIcon);
+ m_closeButton->setFixedSize(12, 12);
+
+ m_titleBarLayout->addWidget(m_addChannelButton);
+ m_titleBarLayout->addWidget(m_titleLabel);
+ m_titleBarLayout->addWidget(m_normalButton);
+ m_titleBarLayout->addWidget(m_closeButton);
+ setTitleBarWidget(m_titleBar);
+
+ QObject::connect(
+ m_addChannelButton,
+ &QPushButton::clicked,
+ this,
+ &ChannelsDock::addChannelDialog
+ );
+
+ QObject::connect(
+ m_normalButton,
+ &QPushButton::clicked,
+ this,
+ &ChannelsDock::toggleFloating
+ );
+
+ QObject::connect(
+ &m_channelAddDialog,
+ &ChannelAddDialog::addChannel,
+ this,
+ &ChannelsDock::addChannelEmitted
+ );
+
+ connect(m_closeButton, SIGNAL(clicked()), this, SLOT(hide()));
+}
+
+ChannelsDock::~ChannelsDock()
+{
+ delete m_closeButton;
+ delete m_normalButton;
+ delete m_titleLabel;
+ delete m_titleBarLayout;
+ delete m_titleBar;
+}
+
+void ChannelsDock::toggleFloating()
+{
+ setFloating(!isFloating());
+}
+
+void ChannelsDock::addChannelDialog()
+{
+ m_channelAddDialog.exec();
+
+}
+
+void ChannelsDock::addChannelEmitted(int channelIndex)
+{
+ if (channelIndex >= 0) {
+ emit addChannel(channelIndex);
+ }
+}
\ No newline at end of file
diff --git a/sdrgui/gui/channelsdock.h b/sdrgui/gui/channelsdock.h
new file mode 100644
index 000000000..96138354e
--- /dev/null
+++ b/sdrgui/gui/channelsdock.h
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2020 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SDRGUI_GUI_CHANNELDOCK_H_
+#define SDRGUI_GUI_CHANNELDOCK_H_
+
+#include
+
+#include "channeladddialog.h"
+
+class QHBoxLayout;
+class QLabel;
+class QPushButton;
+class QStringList;
+
+class ChannelsDock : public QDockWidget
+{
+ Q_OBJECT
+public:
+ ChannelsDock(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
+ ~ChannelsDock();
+
+ void resetAvailableChannels() { m_channelAddDialog.resetChannelNames(); }
+ void addAvailableChannels(const QStringList& channelNames) { m_channelAddDialog.addChannelNames(channelNames); }
+
+private:
+ QPushButton *m_addChannelButton;
+ QWidget *m_titleBar;
+ QHBoxLayout *m_titleBarLayout;
+ QLabel *m_titleLabel;
+ QPushButton *m_normalButton;
+ QPushButton *m_closeButton;
+ ChannelAddDialog m_channelAddDialog;
+
+private slots:
+ void toggleFloating();
+ void addChannelDialog();
+ void addChannelEmitted(int channelIndex);
+
+signals:
+ void addChannel(int);
+};
+
+#endif // SDRGUI_GUI_CHANNELDOCK_H_
diff --git a/sdrgui/gui/samplingdevicecontrol.cpp b/sdrgui/gui/samplingdevicecontrol.cpp
index 43d67c29a..ea716160b 100644
--- a/sdrgui/gui/samplingdevicecontrol.cpp
+++ b/sdrgui/gui/samplingdevicecontrol.cpp
@@ -98,13 +98,3 @@ void SamplingDeviceControl::removeSelectedDeviceIndex()
m_selectedDeviceIndex = -1;
}
-
-QComboBox *SamplingDeviceControl::getChannelSelector()
-{
- return ui->channelSelect;
-}
-
-QPushButton *SamplingDeviceControl::getAddChannelButton()
-{
- return ui->addChannel;
-}
diff --git a/sdrgui/gui/samplingdevicecontrol.h b/sdrgui/gui/samplingdevicecontrol.h
index d329f6627..8b1df2d1d 100644
--- a/sdrgui/gui/samplingdevicecontrol.h
+++ b/sdrgui/gui/samplingdevicecontrol.h
@@ -42,10 +42,7 @@ public:
int getSelectedDeviceIndex() const { return m_selectedDeviceIndex; }
void setSelectedDeviceIndex(int index);
void removeSelectedDeviceIndex();
-
void setPluginManager(PluginManager *pluginManager) { m_pluginManager = pluginManager; }
- QComboBox *getChannelSelector();
- QPushButton *getAddChannelButton();
private slots:
void on_deviceChange_clicked();
diff --git a/sdrgui/gui/samplingdevicecontrol.ui b/sdrgui/gui/samplingdevicecontrol.ui
index 7eb8340b9..337ed1da9 100644
--- a/sdrgui/gui/samplingdevicecontrol.ui
+++ b/sdrgui/gui/samplingdevicecontrol.ui
@@ -7,13 +7,13 @@
0
0
300
- 76
+ 40
300
- 76
+ 40
@@ -104,43 +104,6 @@
- -
-
-
-
-
-
- Select channel plugin
-
-
-
- -
-
-
-
- 24
- 0
-
-
-
-
- 24
- 16777215
-
-
-
- Add a new channel
-
-
-
-
-
-
- :/plusw.png:/plusw.png
-
-
-
-
-
diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp
index bd9f9a750..ed672d427 100644
--- a/sdrgui/mainwindow.cpp
+++ b/sdrgui/mainwindow.cpp
@@ -211,6 +211,7 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse
int deviceIndex = DeviceEnumerator::instance()->getRxSamplingDeviceIndex(m_settings.getSourceDeviceId(), m_settings.getSourceIndex());
addSourceDevice(deviceIndex); // add the first device set with file input device as default if device in settings is not enumerated
m_deviceUIs.back()->m_deviceAPI->setBuddyLeader(true); // the first device is always the leader
+ tabChannelsIndexChanged(); // force channel selection list update
splash->showStatusMessage("load current preset settings...", Qt::white);
qDebug() << "MainWindow::MainWindow: load current preset settings...";
@@ -224,6 +225,8 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse
splash->showStatusMessage("finishing...", Qt::white);
connect(ui->tabInputsView, SIGNAL(currentChanged(int)), this, SLOT(tabInputViewIndexChanged()));
+ connect(ui->tabChannels, SIGNAL(currentChanged(int)), this, SLOT(tabChannelsIndexChanged()));
+ connect(ui->channelDock, SIGNAL(addChannel(int)), this, SLOT(channelAddClicked(int)));
QString applicationDirPath = qApp->applicationDirPath();
@@ -314,11 +317,7 @@ void MainWindow::addSourceDevice(int deviceIndex)
m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
QList channelNames;
m_pluginManager->listRxChannels(channelNames);
- QStringList channelNamesList(channelNames);
- m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector()->addItems(channelNamesList);
- m_deviceUIs.back()->setNumberOfAvailableRxChannels(channelNamesList.size());
-
- connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(channelAddClicked(bool)));
+ m_deviceUIs.back()->setNumberOfAvailableRxChannels(channelNames.size());
dspDeviceSourceEngine->addSink(m_deviceUIs.back()->m_spectrumVis);
ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
@@ -396,11 +395,7 @@ void MainWindow::addSinkDevice()
m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
QList channelNames;
m_pluginManager->listTxChannels(channelNames);
- QStringList channelNamesList(channelNames);
- m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector()->addItems(channelNamesList);
- m_deviceUIs.back()->setNumberOfAvailableTxChannels(channelNamesList.size());
-
- connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(channelAddClicked(bool)));
+ m_deviceUIs.back()->setNumberOfAvailableTxChannels(channelNames.size());
dspDeviceSinkEngine->addSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
m_deviceUIs.back()->m_spectrum->setDisplayedStream(false, 0);
@@ -979,9 +974,7 @@ bool MainWindow::handleMessage(const Message& cmd)
{
MsgAddChannel& notif = (MsgAddChannel&) cmd;
ui->tabInputsSelect->setCurrentIndex(notif.getDeviceSetIndex());
- DeviceUISet *deviceUI = m_deviceUIs[notif.getDeviceSetIndex()];
- deviceUI->m_samplingDeviceControl->getChannelSelector()->setCurrentIndex(notif.getChannelRegistrationIndex());
- channelAddClicked(true);
+ channelAddClicked(notif.getChannelRegistrationIndex());
return true;
}
@@ -1903,9 +1896,8 @@ void MainWindow::sampleMIMOChanged()
}
}
-void MainWindow::channelAddClicked(bool checked)
+void MainWindow::channelAddClicked(int channelIndex)
{
- (void) checked;
// Do it in the currently selected source tab
int currentSourceTabIndex = ui->tabInputsSelect->currentIndex();
@@ -1916,27 +1908,26 @@ void MainWindow::channelAddClicked(bool checked)
if (deviceUI->m_deviceSourceEngine) // source device => Rx channels
{
m_pluginManager->createRxChannelInstance(
- deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI, deviceUI->m_deviceAPI);
+ channelIndex, deviceUI, deviceUI->m_deviceAPI);
}
else if (deviceUI->m_deviceSinkEngine) // sink device => Tx channels
{
m_pluginManager->createTxChannelInstance(
- deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI, deviceUI->m_deviceAPI);
+ channelIndex, deviceUI, deviceUI->m_deviceAPI);
}
else if (deviceUI->m_deviceMIMOEngine) // MIMO device => all possible channels. Depends on index range
{
int nbRxChannels = deviceUI->getNumberOfAvailableRxChannels();
int nbTxChannels = deviceUI->getNumberOfAvailableTxChannels();
- int selectedIndex = deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex();
qDebug("MainWindow::channelAddClicked: MIMO: tab: %d nbRx: %d nbTx: %d selected: %d",
- currentSourceTabIndex, nbRxChannels, nbTxChannels, selectedIndex);
+ currentSourceTabIndex, nbRxChannels, nbTxChannels, channelIndex);
- if (selectedIndex < nbRxChannels) {
+ if (channelIndex < nbRxChannels) {
m_pluginManager->createRxChannelInstance(
- selectedIndex, deviceUI, deviceUI->m_deviceAPI);
- } else if (selectedIndex < nbRxChannels + nbTxChannels) {
+ channelIndex, deviceUI, deviceUI->m_deviceAPI);
+ } else if (channelIndex < nbRxChannels + nbTxChannels) {
m_pluginManager->createTxChannelInstance(
- selectedIndex - nbRxChannels, deviceUI, deviceUI->m_deviceAPI);
+ channelIndex - nbRxChannels, deviceUI, deviceUI->m_deviceAPI);
}
}
}
@@ -1990,6 +1981,38 @@ void MainWindow::tabInputViewIndexChanged()
ui->tabSpectraGUI->setCurrentIndex(inputViewIndex);
}
+void MainWindow::tabChannelsIndexChanged()
+{
+ int channelsTabIndex = ui->tabChannels->currentIndex();
+
+ if (channelsTabIndex >= 0)
+ {
+ DeviceUISet *deviceUI = m_deviceUIs[channelsTabIndex];
+ QList channelNames;
+ ui->channelDock->resetAvailableChannels();
+
+ if (deviceUI->m_deviceSourceEngine) // source device
+ {
+ m_pluginManager->listRxChannels(channelNames);
+ ui->channelDock->addAvailableChannels(channelNames);
+ }
+ else if (deviceUI->m_deviceSinkEngine) // sink device
+ {
+ m_pluginManager->listTxChannels(channelNames);
+ ui->channelDock->addAvailableChannels(channelNames);
+ }
+ else if (deviceUI->m_deviceMIMOEngine) // MIMO device
+ {
+ m_pluginManager->listMIMOChannels(channelNames);
+ ui->channelDock->addAvailableChannels(channelNames);
+ m_pluginManager->listRxChannels(channelNames);
+ ui->channelDock->addAvailableChannels(channelNames);
+ m_pluginManager->listTxChannels(channelNames);
+ ui->channelDock->addAvailableChannels(channelNames);
+ }
+ }
+}
+
void MainWindow::updateStatus()
{
m_dateTimeWidget->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss t"));
diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h
index cdbdcb224..ee7a95db1 100644
--- a/sdrgui/mainwindow.h
+++ b/sdrgui/mainwindow.h
@@ -400,7 +400,7 @@ private slots:
void sampleSourceChanged();
void sampleSinkChanged();
void sampleMIMOChanged();
- void channelAddClicked(bool checked);
+ void channelAddClicked(int channelIndex);
void on_action_Loaded_Plugins_triggered();
void on_action_About_triggered();
void on_action_addSourceDevice_triggered();
@@ -408,6 +408,7 @@ private slots:
void on_action_addMIMODevice_triggered();
void on_action_removeLastDevice_triggered();
void tabInputViewIndexChanged();
+ void tabChannelsIndexChanged();
void commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release);
};
diff --git a/sdrgui/mainwindow.ui b/sdrgui/mainwindow.ui
index 99ce82a4b..c91e54440 100644
--- a/sdrgui/mainwindow.ui
+++ b/sdrgui/mainwindow.ui
@@ -7,7 +7,7 @@
0
0
1012
- 721
+ 811
@@ -64,7 +64,7 @@
0
0
1012
- 20
+ 27
-
+
Channels
@@ -960,6 +960,12 @@
QToolButton
+
+ ChannelsDock
+ QDockWidget
+
+ 1
+
presetTree