SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
mainwindow.cpp
Go to the documentation of this file.
1 // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
3 // written by Christian Daniel //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #include <gui/commandkeyreceiver.h>
20 #include <QInputDialog>
21 #include <QMessageBox>
22 #include <QLabel>
23 #include <QFile>
24 #include <QFileInfo>
25 #include <QFileDialog>
26 #include <QTextStream>
27 #include <QDateTime>
28 #include <QSysInfo>
29 #include <QKeyEvent>
30 #include <QResource>
31 #include <QFontDatabase>
32 
35 #include "device/deviceapi.h"
36 #include "device/deviceuiset.h"
38 #include "gui/indicator.h"
39 #include "gui/presetitem.h"
40 #include "gui/commanditem.h"
41 #include "gui/addpresetdialog.h"
42 #include "gui/editcommanddialog.h"
44 #include "gui/pluginsdialog.h"
45 #include "gui/aboutdialog.h"
46 #include "gui/rollupwidget.h"
47 #include "gui/channelwindow.h"
48 #include "gui/audiodialog.h"
49 #include "gui/loggingdialog.h"
52 #include "gui/sdrangelsplash.h"
53 #include "gui/mypositiondialog.h"
54 #include "gui/ambedevicesdialog.h"
55 #include "dsp/dspengine.h"
56 #include "dsp/spectrumvis.h"
57 #include "dsp/dspcommands.h"
58 #include "dsp/devicesamplesource.h"
59 #include "dsp/devicesamplesink.h"
60 #include "dsp/devicesamplemimo.h"
64 #include "plugin/pluginapi.h"
65 #include "gui/glspectrum.h"
66 #include "gui/glspectrumgui.h"
67 #include "loggerwithfile.h"
69 #include "webapi/webapiserver.h"
71 #include "commands/command.h"
72 
73 #include "mainwindow.h"
74 
76 
77 #include "ui_mainwindow.h"
78 
79 #include <string>
80 #include <QDebug>
81 #include <QSplashScreen>
82 
92 
94 
95 MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parser, QWidget* parent) :
96  QMainWindow(parent),
97  ui(new Ui::MainWindow),
98  m_settings(),
99  m_masterTabIndex(0),
100  m_dspEngine(DSPEngine::instance()),
101  m_lastEngineState(DeviceAPI::StNotStarted),
102  m_inputGUI(0),
103  m_sampleRate(0),
104  m_centerFrequency(0),
105  m_sampleFileName(std::string("./test.sdriq")),
106  m_logger(logger)
107 {
108  qDebug() << "MainWindow::MainWindow: start";
109 
110  m_instance = this;
111 
112  QFontDatabase::addApplicationFont(":/LiberationSans-Regular.ttf");
113  QFontDatabase::addApplicationFont(":/LiberationMono-Regular.ttf");
114 
115  QFont font("Liberation Sans");
116  font.setPointSize(9);
117  qApp->setFont(font);
118 
119  QPixmap logoPixmap(":/sdrangel_logo.png");
120  SDRangelSplash *splash = new SDRangelSplash(logoPixmap);
121  splash->setMessageRect(QRect(10, 80, 350, 16));
122  splash->show();
123  splash->showStatusMessage("starting...", Qt::white);
124 
127 
128  ui->setupUi(this);
129  createStatusBar();
130 
131  setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
132  setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
133  setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
134  setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
135 
136  // work around broken Qt dock widget ordering
137  removeDockWidget(ui->inputViewDock);
138  removeDockWidget(ui->inputSelectDock);
139  removeDockWidget(ui->spectraDisplayDock);
140  removeDockWidget(ui->presetDock);
141  removeDockWidget(ui->commandsDock);
142  removeDockWidget(ui->channelDock);
143  addDockWidget(Qt::LeftDockWidgetArea, ui->inputViewDock);
144  addDockWidget(Qt::LeftDockWidgetArea, ui->inputSelectDock);
145  addDockWidget(Qt::LeftDockWidgetArea, ui->spectraDisplayDock);
146  addDockWidget(Qt::LeftDockWidgetArea, ui->presetDock);
147  addDockWidget(Qt::LeftDockWidgetArea, ui->commandsDock);
148  tabifyDockWidget(ui->presetDock, ui->commandsDock);
149  addDockWidget(Qt::RightDockWidgetArea, ui->channelDock);
150 
151  ui->inputViewDock->show();
152  ui->inputSelectDock->show();
153  ui->spectraDisplayDock->show();
154  ui->presetDock->show();
155  ui->commandsDock->show();
156  ui->channelDock->show();
157 
158  ui->menu_Window->addAction(ui->inputViewDock->toggleViewAction());
159  ui->menu_Window->addAction(ui->inputSelectDock->toggleViewAction());
160  ui->menu_Window->addAction(ui->spectraDisplayDock->toggleViewAction());
161  ui->menu_Window->addAction(ui->presetDock->toggleViewAction());
162  ui->menu_Window->addAction(ui->commandsDock->toggleViewAction());
163  ui->menu_Window->addAction(ui->channelDock->toggleViewAction());
164 
165  ui->tabInputsView->setStyleSheet("QWidget { background: rgb(50,50,50); } "
166  "QToolButton::checked { background: rgb(128,70,0); } "
167  "QComboBox::item:selected { color: rgb(255,140,0); } "
168  "QTabWidget::pane { border: 1px solid #C06900; } "
169  "QTabBar::tab:selected { background: rgb(128,70,0); }");
170  ui->tabInputsSelect->setStyleSheet("QWidget { background: rgb(50,50,50); } "
171  "QToolButton::checked { background: rgb(128,70,0); } "
172  "QComboBox::item:selected { color: rgb(255,140,0); } "
173  "QTabWidget::pane { border: 1px solid #808080; } "
174  "QTabBar::tab:selected { background: rgb(100,100,100); }");
175 
176  connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection);
177 
178  connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
179  m_statusTimer.start(1000);
180 
181  m_masterTimer.setTimerType(Qt::PreciseTimer);
182  m_masterTimer.start(50);
183 
184  splash->showStatusMessage("load settings...", Qt::white);
185  qDebug() << "MainWindow::MainWindow: load settings...";
186 
187  loadSettings();
188 
189  splash->showStatusMessage("load plugins...", Qt::white);
190  qDebug() << "MainWindow::MainWindow: load plugins...";
191 
192  m_pluginManager = new PluginManager(this);
193  m_pluginManager->loadPlugins(QString("plugins"));
194 
195  splash->showStatusMessage("load file input...", Qt::white);
196  qDebug() << "MainWindow::MainWindow: select SampleSource from settings or default (file input)...";
197 
199  addSourceDevice(deviceIndex); // add the first device set with file input device as default if device in settings is not enumerated
200  m_deviceUIs.back()->m_deviceAPI->setBuddyLeader(true); // the first device is always the leader
201 
202  splash->showStatusMessage("load current preset settings...", Qt::white);
203  qDebug() << "MainWindow::MainWindow: load current preset settings...";
204 
206 
207  splash->showStatusMessage("apply settings...", Qt::white);
208  qDebug() << "MainWindow::MainWindow: apply settings...";
209 
210  applySettings();
211 
212  splash->showStatusMessage("update preset controls...", Qt::white);
213  qDebug() << "MainWindow::MainWindow: update preset controls...";
214 
216 
217  splash->showStatusMessage("finishing...", Qt::white);
218  connect(ui->tabInputsView, SIGNAL(currentChanged(int)), this, SLOT(tabInputViewIndexChanged()));
219 
220  QString applicationDirPath = qApp->applicationDirPath();
221 
222 #ifdef _MSC_VER
223  if (QResource::registerResource(applicationDirPath + "/sdrbase.rcc")) {
224  qDebug("MainWindow::MainWindow: registered resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
225  } else {
226  qWarning("MainWindow::MainWindow: could not register resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
227  }
228 #endif
229 
230  m_apiAdapter = new WebAPIAdapterGUI(*this);
233  m_apiHost = parser.getServerAddress();
234  m_apiPort = parser.getServerPort();
236  m_apiServer->start();
237 
240  this->installEventFilter(m_commandKeyReceiver);
241 
243 
244  delete splash;
245 
246  qDebug() << "MainWindow::MainWindow: end";
247 }
248 
250 {
251  m_apiServer->stop();
252  delete m_apiServer;
253  delete m_requestMapper;
254  delete m_apiAdapter;
255 
256  delete m_pluginManager;
257  delete m_dateTimeWidget;
258  delete m_showSystemWidget;
259 
260  delete ui;
261 
262  qDebug() << "MainWindow::~MainWindow: end";
263  delete m_logger;
264  delete m_commandKeyReceiver;
265 }
266 
267 void MainWindow::addSourceDevice(int deviceIndex)
268 {
269  DSPDeviceSourceEngine *dspDeviceSourceEngine = m_dspEngine->addDeviceSourceEngine();
270  dspDeviceSourceEngine->start();
271 
272  uint dspDeviceSourceEngineUID = dspDeviceSourceEngine->getUID();
273  char uidCStr[16];
274  sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID);
275 
276  int deviceTabIndex = m_deviceUIs.size();
277  m_deviceUIs.push_back(new DeviceUISet(deviceTabIndex, 0, m_masterTimer));
278  m_deviceUIs.back()->m_deviceSourceEngine = dspDeviceSourceEngine;
279 
280  char tabNameCStr[16];
281  sprintf(tabNameCStr, "R%d", deviceTabIndex);
282 
283  DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleRx, deviceTabIndex, dspDeviceSourceEngine, nullptr, nullptr);
284 
285  m_deviceUIs.back()->m_deviceAPI = deviceAPI;
286  m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
287  QList<QString> channelNames;
288  m_pluginManager->listRxChannels(channelNames);
289  QStringList channelNamesList(channelNames);
290  m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector()->addItems(channelNamesList);
291  m_deviceUIs.back()->setNumberOfAvailableRxChannels(channelNamesList.size());
292 
293  connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(channelAddClicked(bool)));
294 
295  dspDeviceSourceEngine->addSink(m_deviceUIs.back()->m_spectrumVis);
296  ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
297  ui->tabSpectraGUI->addTab(m_deviceUIs.back()->m_spectrumGUI, tabNameCStr);
298  ui->tabChannels->addTab(m_deviceUIs.back()->m_channelWindow, tabNameCStr);
299 
300  connect(m_deviceUIs.back()->m_samplingDeviceControl, SIGNAL(changed()), this, SLOT(sampleSourceChanged()));
301 
302  ui->tabInputsSelect->addTab(m_deviceUIs.back()->m_samplingDeviceControl, tabNameCStr);
303  ui->tabInputsSelect->setTabToolTip(deviceTabIndex, QString(uidCStr));
304 
305  // Create a file source instance by default if requested device was not enumerated (index = -1)
306  if (deviceIndex < 0) {
308  }
309 
311  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
312  m_deviceUIs.back()->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
313  m_deviceUIs.back()->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
314  m_deviceUIs.back()->m_deviceAPI->setHardwareId(samplingDevice->hardwareId);
315  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceId(samplingDevice->id);
316  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial);
317  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
318  m_deviceUIs.back()->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getRxPluginInterface(deviceIndex));
319 
320  QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence);
321 
322  if (userArgs.size() > 0) {
323  m_deviceUIs.back()->m_deviceAPI->setHardwareUserArguments(userArgs);
324  }
325 
326  m_deviceUIs.back()->m_samplingDeviceControl->setSelectedDeviceIndex(deviceIndex);
327 
328  // delete previous plugin GUI
329  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI(
330  m_deviceUIs.back()->m_deviceAPI->getSamplingDevicePluginInstanceGUI());
331 
332 
333  DeviceSampleSource *source = m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->createSampleSourcePluginInstance(
334  m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceId(), m_deviceUIs.back()->m_deviceAPI);
335  m_deviceUIs.back()->m_deviceAPI->setSampleSource(source);
336  QWidget *gui;
337  PluginInstanceGUI *pluginGUI = m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->createSampleSourcePluginInstanceGUI(
338  m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceId(),
339  &gui,
340  m_deviceUIs.back());
341  m_deviceUIs.back()->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(pluginGUI->getInputMessageQueue());
342  m_deviceUIs.back()->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginGUI);
343  m_deviceUIs.back()->m_deviceAPI->getSampleSource()->init();
344  setDeviceGUI(deviceTabIndex, gui, m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceDisplayName());
345 }
346 
348 {
349  DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine();
350  dspDeviceSinkEngine->start();
351 
352  uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID();
353  char uidCStr[16];
354  sprintf(uidCStr, "UID:%d", dspDeviceSinkEngineUID);
355 
356  int deviceTabIndex = m_deviceUIs.size();
357  m_deviceUIs.push_back(new DeviceUISet(deviceTabIndex, 1, m_masterTimer));
358  m_deviceUIs.back()->m_deviceSourceEngine = 0;
359  m_deviceUIs.back()->m_deviceSinkEngine = dspDeviceSinkEngine;
360 
361  char tabNameCStr[16];
362  sprintf(tabNameCStr, "T%d", deviceTabIndex);
363 
364  DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamSingleTx, deviceTabIndex, nullptr, dspDeviceSinkEngine, nullptr);
365 
366  m_deviceUIs.back()->m_deviceAPI = deviceAPI;
367  m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
368  QList<QString> channelNames;
369  m_pluginManager->listTxChannels(channelNames);
370  QStringList channelNamesList(channelNames);
371  m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector()->addItems(channelNamesList);
372  m_deviceUIs.back()->setNumberOfAvailableTxChannels(channelNamesList.size());
373 
374  connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(channelAddClicked(bool)));
375 
376  dspDeviceSinkEngine->addSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
377  m_deviceUIs.back()->m_spectrum->setDisplayedStream(false, 0);
378  ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
379  ui->tabSpectraGUI->addTab(m_deviceUIs.back()->m_spectrumGUI, tabNameCStr);
380  ui->tabChannels->addTab(m_deviceUIs.back()->m_channelWindow, tabNameCStr);
381 
382  connect(m_deviceUIs.back()->m_samplingDeviceControl, SIGNAL(changed()), this, SLOT(sampleSinkChanged()));
383 
384  ui->tabInputsSelect->addTab(m_deviceUIs.back()->m_samplingDeviceControl, tabNameCStr);
385  ui->tabInputsSelect->setTabToolTip(deviceTabIndex, QString(uidCStr));
386 
387  // create a file sink by default
388  int fileSinkDeviceIndex = DeviceEnumerator::instance()->getFileSinkDeviceIndex();
389  const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(fileSinkDeviceIndex);
390  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
391  m_deviceUIs.back()->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
392  m_deviceUIs.back()->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
393  m_deviceUIs.back()->m_deviceAPI->setHardwareId(samplingDevice->hardwareId);
394  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceId(samplingDevice->id);
395  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial);
396  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
397  m_deviceUIs.back()->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getTxPluginInterface(fileSinkDeviceIndex));
398 
399  QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence);
400 
401  if (userArgs.size() > 0) {
402  m_deviceUIs.back()->m_deviceAPI->setHardwareUserArguments(userArgs);
403  }
404 
405  m_deviceUIs.back()->m_samplingDeviceControl->setSelectedDeviceIndex(fileSinkDeviceIndex);
406 
407  // delete previous plugin GUI if it exists
408  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI(
409  m_deviceUIs.back()->m_deviceAPI->getSamplingDevicePluginInstanceGUI());
410 
411  DeviceSampleSink *sink = m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->createSampleSinkPluginInstance(
412  m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceId(), m_deviceUIs.back()->m_deviceAPI);
413  m_deviceUIs.back()->m_deviceAPI->setSampleSink(sink);
414  QWidget *gui;
415  PluginInstanceGUI *pluginUI = m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->createSampleSinkPluginInstanceGUI(
416  m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceId(),
417  &gui,
418  m_deviceUIs.back());
419  m_deviceUIs.back()->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(pluginUI->getInputMessageQueue());
420  m_deviceUIs.back()->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginUI);
421  m_deviceUIs.back()->m_deviceAPI->getSampleSink()->init();
422  setDeviceGUI(deviceTabIndex, gui, m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceDisplayName(), 1);
423 }
424 
426 {
427  DSPDeviceMIMOEngine *dspDeviceMIMOEngine = m_dspEngine->addDeviceMIMOEngine();
428  dspDeviceMIMOEngine->start();
429 
430  uint dspDeviceMIMOEngineUID = dspDeviceMIMOEngine->getUID();
431  char uidCStr[16];
432  sprintf(uidCStr, "UID:%d", dspDeviceMIMOEngineUID);
433 
434  int deviceTabIndex = m_deviceUIs.size();
435  m_deviceUIs.push_back(new DeviceUISet(deviceTabIndex, 2, m_masterTimer));
436  m_deviceUIs.back()->m_deviceSourceEngine = nullptr;
437  m_deviceUIs.back()->m_deviceSinkEngine = nullptr;
438  m_deviceUIs.back()->m_deviceMIMOEngine = dspDeviceMIMOEngine;
439 
440  char tabNameCStr[16];
441  sprintf(tabNameCStr, "M%d", deviceTabIndex);
442 
443  DeviceAPI *deviceAPI = new DeviceAPI(DeviceAPI::StreamMIMO, deviceTabIndex, nullptr, nullptr, dspDeviceMIMOEngine);
444 
445  m_deviceUIs.back()->m_deviceAPI = deviceAPI;
446  m_deviceUIs.back()->m_samplingDeviceControl->setPluginManager(m_pluginManager);
447  QComboBox *channelSelector = m_deviceUIs.back()->m_samplingDeviceControl->getChannelSelector();
448  // Add Rx channels
449  QList<QString> rxChannelNames;
450  m_pluginManager->listRxChannels(rxChannelNames);
451  QStringList rxChannelNamesList(rxChannelNames);
452  channelSelector->addItems(rxChannelNamesList);
453  m_deviceUIs.back()->setNumberOfAvailableRxChannels(rxChannelNamesList.size());
454  // Add Tx channels
455  QList<QString> txChannelNames;
456  m_pluginManager->listTxChannels(txChannelNames);
457  QStringList txChannelNamesList(txChannelNames);
458  channelSelector->addItems(txChannelNamesList);
459  m_deviceUIs.back()->setNumberOfAvailableTxChannels(txChannelNamesList.size());
460  // TODO: add MIMO channels
461 
462  connect(m_deviceUIs.back()->m_samplingDeviceControl->getAddChannelButton(), SIGNAL(clicked(bool)), this, SLOT(channelAddClicked(bool)));
463 
464  dspDeviceMIMOEngine->addSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
465  ui->tabSpectra->addTab(m_deviceUIs.back()->m_spectrum, tabNameCStr);
466  ui->tabSpectraGUI->addTab(m_deviceUIs.back()->m_spectrumGUI, tabNameCStr);
467  ui->tabChannels->addTab(m_deviceUIs.back()->m_channelWindow, tabNameCStr);
468 
469  connect(m_deviceUIs.back()->m_samplingDeviceControl, SIGNAL(changed()), this, SLOT(sampleMIMOChanged()));
470 
471  ui->tabInputsSelect->addTab(m_deviceUIs.back()->m_samplingDeviceControl, tabNameCStr);
472  ui->tabInputsSelect->setTabToolTip(deviceTabIndex, QString(uidCStr));
473 
474  // create a test MIMO by default
475  int testMIMODeviceIndex = DeviceEnumerator::instance()->getTestMIMODeviceIndex();
476  const PluginInterface::SamplingDevice *samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(testMIMODeviceIndex);
477  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
478  m_deviceUIs.back()->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
479  m_deviceUIs.back()->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
480  m_deviceUIs.back()->m_deviceAPI->setHardwareId(samplingDevice->hardwareId);
481  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceId(samplingDevice->id);
482  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial);
483  m_deviceUIs.back()->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
484  m_deviceUIs.back()->m_deviceAPI->setSamplingDevicePluginInterface(DeviceEnumerator::instance()->getMIMOPluginInterface(testMIMODeviceIndex));
485 
486  QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence);
487 
488  if (userArgs.size() > 0) {
489  m_deviceUIs.back()->m_deviceAPI->setHardwareUserArguments(userArgs);
490  }
491 
492  m_deviceUIs.back()->m_samplingDeviceControl->setSelectedDeviceIndex(testMIMODeviceIndex);
493 
494  // delete previous plugin GUI if it exists
495  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI(
496  m_deviceUIs.back()->m_deviceAPI->getSamplingDevicePluginInstanceGUI());
497 
498  DeviceSampleMIMO *mimo = m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->createSampleMIMOPluginInstance(
499  m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceId(), m_deviceUIs.back()->m_deviceAPI);
500  m_deviceUIs.back()->m_deviceAPI->setSampleMIMO(mimo);
501  QWidget *gui;
502  PluginInstanceGUI *pluginUI = m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->createSampleMIMOPluginInstanceGUI(
503  m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceId(),
504  &gui,
505  m_deviceUIs.back());
506  m_deviceUIs.back()->m_deviceAPI->getSampleMIMO()->setMessageQueueToGUI(pluginUI->getInputMessageQueue());
507  m_deviceUIs.back()->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginUI);
508  m_deviceUIs.back()->m_deviceAPI->getSampleMIMO()->init();
509  setDeviceGUI(deviceTabIndex, gui, m_deviceUIs.back()->m_deviceAPI->getSamplingDeviceDisplayName(), 2);
510 }
511 
513 {
514  if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab
515  {
516  DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine;
517  lastDeviceEngine->stopAcquistion();
518  lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis);
519 
520  ui->tabSpectraGUI->removeTab(ui->tabSpectraGUI->count() - 1);
521  ui->tabSpectra->removeTab(ui->tabSpectra->count() - 1);
522 
523  // deletes old UI and input object
524  m_deviceUIs.back()->freeRxChannels(); // destroys the channel instances
525  m_deviceUIs.back()->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(0); // have source stop sending messages to the GUI
526  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI(
527  m_deviceUIs.back()->m_deviceAPI->getSamplingDevicePluginInstanceGUI());
528  m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
529  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput(
530  m_deviceUIs.back()->m_deviceAPI->getSampleSource());
531  m_deviceUIs.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
532  m_deviceUIs.back()->m_samplingDeviceControl->removeSelectedDeviceIndex(); // This releases the device in the device list
533 
534  ui->tabChannels->removeTab(ui->tabChannels->count() - 1);
535 
536  ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1);
537 
538  m_deviceWidgetTabs.removeLast();
539  ui->tabInputsView->clear();
540 
541  for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
542  {
543  qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
544  ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
545  ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
546  }
547 
548  DeviceAPI *sourceAPI = m_deviceUIs.back()->m_deviceAPI;
549  delete m_deviceUIs.back();
550 
551  lastDeviceEngine->stop();
553 
554  delete sourceAPI;
555  }
556  else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab
557  {
558  DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine;
559  lastDeviceEngine->stopGeneration();
560  lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
561 
562  ui->tabSpectraGUI->removeTab(ui->tabSpectraGUI->count() - 1);
563  ui->tabSpectra->removeTab(ui->tabSpectra->count() - 1);
564 
565  // deletes old UI and output object
566  m_deviceUIs.back()->freeTxChannels();
567  m_deviceUIs.back()->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(0); // have sink stop sending messages to the GUI
568  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceGUI(
569  m_deviceUIs.back()->m_deviceAPI->getSamplingDevicePluginInstanceGUI());
570  m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
571  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput(
572  m_deviceUIs.back()->m_deviceAPI->getSampleSink());
573  m_deviceUIs.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
574  m_deviceUIs.back()->m_samplingDeviceControl->removeSelectedDeviceIndex(); // This releases the device in the device list
575 
576  ui->tabChannels->removeTab(ui->tabChannels->count() - 1);
577 
578  ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1);
579 
580  m_deviceWidgetTabs.removeLast();
581  ui->tabInputsView->clear();
582 
583  for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
584  {
585  qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
586  ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
587  ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
588  }
589 
590  DeviceAPI *sinkAPI = m_deviceUIs.back()->m_deviceAPI;
591  delete m_deviceUIs.back();
592 
593  lastDeviceEngine->stop();
595 
596  delete sinkAPI;
597  }
598  else if (m_deviceUIs.back()->m_deviceMIMOEngine) // MIMO tab
599  {
600  DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceMIMOEngine;
601  lastDeviceEngine->stopProcess();
602  lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis);
603 
604  ui->tabSpectraGUI->removeTab(ui->tabSpectraGUI->count() - 1);
605  ui->tabSpectra->removeTab(ui->tabSpectra->count() - 1);
606 
607  // deletes old UI and output object
608  m_deviceUIs.back()->freeRxChannels();
609  m_deviceUIs.back()->freeTxChannels();
610  m_deviceUIs.back()->m_deviceAPI->getSampleMIMO()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI
611  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleMIMOPluginInstanceGUI(
612  m_deviceUIs.back()->m_deviceAPI->getSamplingDevicePluginInstanceGUI());
613  m_deviceUIs.back()->m_deviceAPI->resetSamplingDeviceId();
614  m_deviceUIs.back()->m_deviceAPI->getPluginInterface()->deleteSampleMIMOPluginInstanceMIMO(
615  m_deviceUIs.back()->m_deviceAPI->getSampleMIMO());
616  m_deviceUIs.back()->m_samplingDeviceControl->removeSelectedDeviceIndex(); // This releases the device in the device list
617 
618  ui->tabChannels->removeTab(ui->tabChannels->count() - 1);
619  ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1);
620 
621  m_deviceWidgetTabs.removeLast();
622  ui->tabInputsView->clear();
623 
624  for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
625  {
626  qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
627  ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
628  ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
629  }
630 
631  DeviceAPI *mimoAPI = m_deviceUIs.back()->m_deviceAPI;
632  delete m_deviceUIs.back();
633 
634  lastDeviceEngine->stop();
636 
637  delete mimoAPI;
638  }
639 
640  m_deviceUIs.pop_back();
641 }
642 
643 void MainWindow::deleteChannel(int deviceSetIndex, int channelIndex)
644 {
645  if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_deviceUIs.size()))
646  {
647  DeviceUISet *deviceSet = m_deviceUIs[deviceSetIndex];
648 
649  if (deviceSet->m_deviceSourceEngine) // source device => Rx channels
650  {
651  deviceSet->deleteRxChannel(channelIndex);
652  }
653  else if (deviceSet->m_deviceSinkEngine) // sink device => Tx channels
654  {
655  deviceSet->deleteTxChannel(channelIndex);
656  }
657  }
658 }
659 
660 void MainWindow::addChannelRollup(int deviceTabIndex, QWidget* widget)
661 {
662  if (deviceTabIndex < ui->tabInputsView->count())
663  {
664  DeviceUISet *deviceUI = m_deviceUIs[deviceTabIndex];
665  deviceUI->m_channelWindow->addRollupWidget(widget);
666  ui->channelDock->show();
667  ui->channelDock->raise();
668  }
669 }
670 
671 void MainWindow::addViewAction(QAction* action)
672 {
673  ui->menu_Window->addAction(action);
674 }
675 
676 void MainWindow::setDeviceGUI(int deviceTabIndex, QWidget* gui, const QString& deviceDisplayName, int deviceType)
677 {
678  char tabNameCStr[16];
679 
680  if (deviceType == 0) {
681  sprintf(tabNameCStr, "R%d", deviceTabIndex);
682  } else if (deviceType == 1) {
683  sprintf(tabNameCStr, "T%d", deviceTabIndex);
684  } else if (deviceType == 2) {
685  sprintf(tabNameCStr, "M%d", deviceTabIndex);
686  }
687 
688  qDebug("MainWindow::setDeviceGUI: insert device type %d tab at %d", deviceType, deviceTabIndex);
689 
690  if (deviceTabIndex < m_deviceWidgetTabs.size()) {
691  m_deviceWidgetTabs[deviceTabIndex] = {gui, deviceDisplayName, QString(tabNameCStr)};
692  } else {
693  m_deviceWidgetTabs.append({gui, deviceDisplayName, QString(tabNameCStr)});
694  }
695 
696  ui->tabInputsView->clear();
697 
698  for (int i = 0; i < m_deviceWidgetTabs.size(); i++)
699  {
700  qDebug("MainWindow::setDeviceGUI: adding tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str());
701  ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName);
702  ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName);
703  }
704 
705  ui->tabInputsView->setCurrentIndex(deviceTabIndex);
706 }
707 
709 {
710  qDebug() << "MainWindow::loadSettings";
711 
712  m_settings.load();
714  int middleIndex = m_settings.getPresetCount() / 2;
715  QTreeWidgetItem *treeItem;
716 
717  for (int i = 0; i < m_settings.getPresetCount(); ++i)
718  {
719  treeItem = addPresetToTree(m_settings.getPreset(i));
720 
721  if (i == middleIndex) {
722  ui->presetTree->setCurrentItem(treeItem);
723  }
724  }
725 
727 
728  for (int i = 0; i < m_settings.getCommandCount(); ++i)
729  {
731  }
732 
734 }
735 
736 void MainWindow::loadPresetSettings(const Preset* preset, int tabIndex)
737 {
738  qDebug("MainWindow::loadPresetSettings: preset [%s | %s]",
739  qPrintable(preset->getGroup()),
740  qPrintable(preset->getDescription()));
741 
742  if (tabIndex >= 0)
743  {
744  DeviceUISet *deviceUI = m_deviceUIs[tabIndex];
745 
746  if (deviceUI->m_deviceSourceEngine) // source device
747  {
748  deviceUI->m_spectrumGUI->deserialize(preset->getSpectrumConfig());
749  deviceUI->m_deviceAPI->loadSamplingDeviceSettings(preset);
750  deviceUI->loadRxChannelSettings(preset, m_pluginManager->getPluginAPI());
751  }
752  else if (deviceUI->m_deviceSinkEngine) // sink device
753  {
754  deviceUI->m_spectrumGUI->deserialize(preset->getSpectrumConfig());
755  deviceUI->m_deviceAPI->loadSamplingDeviceSettings(preset);
756  deviceUI->loadTxChannelSettings(preset, m_pluginManager->getPluginAPI());
757  }
758  }
759 
760  // has to be last step
761  restoreState(preset->getLayout());
762  tabifyDockWidget(ui->presetDock, ui->commandsDock); // override this setting
763  ui->presetDock->raise();
764 }
765 
766 void MainWindow::savePresetSettings(Preset* preset, int tabIndex)
767 {
768  qDebug("MainWindow::savePresetSettings: preset [%s | %s]",
769  qPrintable(preset->getGroup()),
770  qPrintable(preset->getDescription()));
771 
772  // Save from currently selected source tab
773  //int currentSourceTabIndex = ui->tabInputsView->currentIndex();
774  DeviceUISet *deviceUI = m_deviceUIs[tabIndex];
775 
776  if (deviceUI->m_deviceSourceEngine) // source device
777  {
778  preset->setSpectrumConfig(deviceUI->m_spectrumGUI->serialize());
779  preset->clearChannels();
780  deviceUI->saveRxChannelSettings(preset);
781  deviceUI->m_deviceAPI->saveSamplingDeviceSettings(preset);
782  }
783  else if (deviceUI->m_deviceSinkEngine) // sink device
784  {
785  preset->setSpectrumConfig(deviceUI->m_spectrumGUI->serialize());
786  preset->clearChannels();
787  preset->setSourcePreset(false);
788  deviceUI->saveTxChannelSettings(preset);
789  deviceUI->m_deviceAPI->saveSamplingDeviceSettings(preset);
790  }
791 
792  preset->setLayout(saveState());
793 }
794 
796 {
797 }
798 
800 {
801  QString qtVersionStr = QString("Qt %1 ").arg(QT_VERSION_STR);
802 #if QT_VERSION >= 0x050400
803  m_showSystemWidget = new QLabel("SDRangel " + qApp->applicationVersion() + " " + qtVersionStr
804  + QSysInfo::currentCpuArchitecture() + " " + QSysInfo::prettyProductName(), this);
805 #else
806  m_showSystemWidget = new QLabel("SDRangel " + qApp->applicationVersion() + " " + qtVersionStr, this);
807 #endif
808  statusBar()->addPermanentWidget(m_showSystemWidget);
809 
810  m_dateTimeWidget = new QLabel(tr("Date"), this);
811  m_dateTimeWidget->setToolTip(tr("Current date/time"));
812  statusBar()->addPermanentWidget(m_dateTimeWidget);
813 }
814 
816 {
817  qDebug("MainWindow::closeEvent");
818 
820  m_settings.save();
821 
822  while (m_deviceUIs.size() > 0)
823  {
825  }
826 
827  closeEvent->accept();
828 }
829 
831 {
832  ui->presetTree->resizeColumnToContents(0);
833 
834  if(ui->presetTree->currentItem() != 0)
835  {
836  ui->presetDelete->setEnabled(true);
837  ui->presetLoad->setEnabled(true);
838  }
839  else
840  {
841  ui->presetDelete->setEnabled(false);
842  ui->presetLoad->setEnabled(false);
843  }
844 }
845 
846 QTreeWidgetItem* MainWindow::addPresetToTree(const Preset* preset)
847 {
848  QTreeWidgetItem* group = 0;
849 
850  for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++)
851  {
852  if(ui->presetTree->topLevelItem(i)->text(0) == preset->getGroup())
853  {
854  group = ui->presetTree->topLevelItem(i);
855  break;
856  }
857  }
858 
859  if(group == 0)
860  {
861  QStringList sl;
862  sl.append(preset->getGroup());
863  group = new QTreeWidgetItem(ui->presetTree, sl, PGroup);
864  group->setFirstColumnSpanned(true);
865  group->setExpanded(true);
866  ui->presetTree->sortByColumn(0, Qt::AscendingOrder);
867  }
868 
869  QStringList sl;
870  sl.append(QString("%1").arg(preset->getCenterFrequency() / 1e6f, 0, 'f', 3)); // frequency column
871  sl.append(QString("%1").arg(preset->isSourcePreset() ? 'R' : 'T')); // mode column
872  sl.append(preset->getDescription()); // description column
873  PresetItem* item = new PresetItem(group, sl, preset->getCenterFrequency(), PItem);
874  item->setTextAlignment(0, Qt::AlignRight);
875  item->setData(0, Qt::UserRole, qVariantFromValue(preset));
876  ui->presetTree->resizeColumnToContents(0); // Resize frequency column to minimum
877  ui->presetTree->resizeColumnToContents(1); // Resize mode column to minimum
878 
880  return item;
881 }
882 
883 QTreeWidgetItem* MainWindow::addCommandToTree(const Command* command)
884 {
885  QTreeWidgetItem* group = 0;
886 
887  for(int i = 0; i < ui->commandTree->topLevelItemCount(); i++)
888  {
889  if(ui->commandTree->topLevelItem(i)->text(0) == command->getGroup())
890  {
891  group = ui->commandTree->topLevelItem(i);
892  break;
893  }
894  }
895 
896  if(group == 0)
897  {
898  QStringList sl;
899  sl.append(command->getGroup());
900  group = new QTreeWidgetItem(ui->commandTree, sl, PGroup);
901  group->setFirstColumnSpanned(true);
902  group->setExpanded(true);
903  ui->commandTree->sortByColumn(0, Qt::AscendingOrder);
904  }
905 
906  QStringList sl;
907  sl.append(QString("%1").arg(command->getDescription())); // Descriptions column
908  sl.append(QString("%1").arg(command->getAssociateKey() ? command->getRelease() ? "R" : "P" : "-")); // key press/release column
909  sl.append(QString("%1").arg(command->getKeyLabel())); // key column
910  CommandItem* item = new CommandItem(group, sl, command->getDescription(), PItem);
911  item->setData(0, Qt::UserRole, qVariantFromValue(command));
912  item->setTextAlignment(0, Qt::AlignLeft);
913  ui->commandTree->resizeColumnToContents(0); // Resize description column to minimum
914  ui->commandTree->resizeColumnToContents(1); // Resize key column to minimum
915  ui->commandTree->resizeColumnToContents(2); // Resize key press/release column to minimum
916 
917  //updatePresetControls();
918  return item;
919 }
920 
922 {
923 }
924 
926 {
927  if (MsgLoadPreset::match(cmd))
928  {
929  MsgLoadPreset& notif = (MsgLoadPreset&) cmd;
931  return true;
932  }
933  else if (MsgSavePreset::match(cmd))
934  {
935  MsgSavePreset& notif = (MsgSavePreset&) cmd;
937  if (notif.isNewPreset()) { ui->presetTree->setCurrentItem(addPresetToTree(notif.getPreset())); }
939  m_settings.save();
940  return true;
941  }
942  else if (MsgDeletePreset::match(cmd))
943  {
944  MsgDeletePreset& notif = (MsgDeletePreset&) cmd;
945  const Preset *presetToDelete = notif.getPreset();
946 
947  // remove preset from tree
948  for (int ig = 0; ig < ui->presetTree->topLevelItemCount(); ig++)
949  {
950  QTreeWidgetItem *groupItem = ui->presetTree->topLevelItem(ig);
951  if (groupItem->text(0) == presetToDelete->getGroup())
952  {
953  for (int ip = 0; ip < groupItem->childCount(); ip++)
954  {
955  QTreeWidgetItem *presetItem = groupItem->child(ip);
956  const Preset* preset = qvariant_cast<const Preset*>(presetItem->data(0, Qt::UserRole));
957 
958  if ((preset->getGroup() == presetToDelete->getGroup()) &&
959  (preset->getCenterFrequency() == presetToDelete->getCenterFrequency()) &&
960  (preset->getDescription() == presetToDelete->getDescription()) &&
961  (preset->isSourcePreset() == presetToDelete->isSourcePreset()))
962  {
963  groupItem->takeChild(ip);
964  }
965  }
966  }
967  }
968 
969  // remove preset from settings
970  m_settings.deletePreset(presetToDelete);
971  return true;
972  }
973  else if (MsgAddDeviceSet::match(cmd))
974  {
975  MsgAddDeviceSet& notif = (MsgAddDeviceSet&) cmd;
976  int direction = notif.getDirection();
977 
978  if (direction == 1) { // Single stream Tx
979  addSinkDevice();
980  } else if (direction == 0) { // Single stream Rx
981  addSourceDevice(-1); // create with file source device by default
982  } else if (direction == 2) { // MIMO
983  addMIMODevice();
984  }
985 
986  return true;
987  }
988  else if (MsgRemoveLastDeviceSet::match(cmd))
989  {
990  if (m_deviceUIs.size() > 1) {
992  }
993 
994  return true;
995  }
996  else if (MsgSetDevice::match(cmd))
997  {
998  MsgSetDevice& notif = (MsgSetDevice&) cmd;
999  ui->tabInputsSelect->setCurrentIndex(notif.getDeviceSetIndex());
1000  DeviceUISet *deviceUI = m_deviceUIs[notif.getDeviceSetIndex()];
1002 
1003  if (notif.getDeviceType() == 1) {
1005  } else if (notif.getDeviceType() == 0) {
1007  } else if (notif.getDeviceType() == 2) {
1009  }
1010 
1011  return true;
1012  }
1013  else if (MsgAddChannel::match(cmd))
1014  {
1015  MsgAddChannel& notif = (MsgAddChannel&) cmd;
1016  ui->tabInputsSelect->setCurrentIndex(notif.getDeviceSetIndex());
1017  DeviceUISet *deviceUI = m_deviceUIs[notif.getDeviceSetIndex()];
1018  deviceUI->m_samplingDeviceControl->getChannelSelector()->setCurrentIndex(notif.getChannelRegistrationIndex());
1019  channelAddClicked(true);
1020 
1021  return true;
1022  }
1023  else if (MsgDeleteChannel::match(cmd))
1024  {
1025  MsgDeleteChannel& notif = (MsgDeleteChannel&) cmd;
1027  return true;
1028  }
1029  else if (MsgDeviceSetFocus::match(cmd))
1030  {
1031  MsgDeviceSetFocus& notif = (MsgDeviceSetFocus&) cmd;
1032  int index = notif.getDeviceSetIndex();
1033  if ((index >= 0) && (index < (int) m_deviceUIs.size())) {
1034  ui->tabInputsView->setCurrentIndex(index);
1035  }
1036  }
1037 
1038  return false;
1039 }
1040 
1042 {
1043  Message* message;
1044 
1045  while ((message = m_inputMessageQueue.pop()) != 0)
1046  {
1047  qDebug("MainWindow::handleMessages: message: %s", message->getIdentifier());
1048  handleMessage(*message);
1049  delete message;
1050  }
1051 }
1052 
1054 {
1055  if(checked) {
1056  showFullScreen();
1057  } else {
1058  showNormal();
1059  }
1060 }
1061 
1063 {
1064  QStringList groups;
1065  QString group = "";
1066  QString description = "";
1067 
1068  for(int i = 0; i < ui->commandTree->topLevelItemCount(); i++) {
1069  groups.append(ui->commandTree->topLevelItem(i)->text(0));
1070  }
1071 
1072  QTreeWidgetItem* item = ui->commandTree->currentItem();
1073 
1074  if(item != 0)
1075  {
1076  if(item->type() == PGroup) {
1077  group = item->text(0);
1078  } else if(item->type() == PItem) {
1079  group = item->parent()->text(0);
1080  description = item->text(0);
1081  }
1082  }
1083 
1084  Command *command = new Command();
1085  command->setGroup(group);
1086  command->setDescription(description);
1087  EditCommandDialog editCommandDialog(groups, group, this);
1088  editCommandDialog.fromCommand(*command);
1089 
1090  if (editCommandDialog.exec() == QDialog::Accepted)
1091  {
1092  editCommandDialog.toCommand(*command);
1093  m_settings.addCommand(command);
1094  ui->commandTree->setCurrentItem(addCommandToTree(command));
1096  }
1097 }
1098 
1100 {
1101  QTreeWidgetItem* item = ui->commandTree->currentItem();
1102  const Command* command = qvariant_cast<const Command*>(item->data(0, Qt::UserRole));
1103  Command *commandCopy = new Command(*command);
1104  m_settings.addCommand(commandCopy);
1105  ui->commandTree->setCurrentItem(addCommandToTree(commandCopy));
1107 }
1108 
1110 {
1111  QTreeWidgetItem* item = ui->commandTree->currentItem();
1112  bool change = false;
1113  const Command *changedCommand = 0;
1114  QString newGroupName;
1115 
1116  QStringList groups;
1117 
1118  for(int i = 0; i < ui->commandTree->topLevelItemCount(); i++) {
1119  groups.append(ui->commandTree->topLevelItem(i)->text(0));
1120  }
1121 
1122  if(item != 0)
1123  {
1124  if (item->type() == PItem)
1125  {
1126  const Command* command = qvariant_cast<const Command*>(item->data(0, Qt::UserRole));
1127 
1128  if (command != 0)
1129  {
1130  EditCommandDialog editCommandDialog(groups, command->getGroup(), this);
1131  editCommandDialog.fromCommand(*command);
1132 
1133  if (editCommandDialog.exec() == QDialog::Accepted)
1134  {
1135  Command* command_mod = const_cast<Command*>(command);
1136  editCommandDialog.toCommand(*command_mod);
1137  change = true;
1138  changedCommand = command;
1139  }
1140  }
1141  }
1142  else if (item->type() == PGroup)
1143  {
1144  AddPresetDialog dlg(groups, item->text(0), this);
1145  dlg.showGroupOnly();
1146  dlg.setDialogTitle("Edit command group");
1147  dlg.setDescriptionBoxTitle("Command details");
1148 
1149  if (dlg.exec() == QDialog::Accepted)
1150  {
1151  m_settings.renameCommandGroup(item->text(0), dlg.group());
1152  newGroupName = dlg.group();
1153  change = true;
1154  }
1155  }
1156  }
1157 
1158  if (change)
1159  {
1161  ui->commandTree->clear();
1162 
1163  for (int i = 0; i < m_settings.getCommandCount(); ++i)
1164  {
1165  QTreeWidgetItem *item_x = addCommandToTree(m_settings.getCommand(i));
1166  const Command* command_x = qvariant_cast<const Command*>(item_x->data(0, Qt::UserRole));
1167  if (changedCommand && (command_x == changedCommand)) { // set cursor on changed command
1168  ui->commandTree->setCurrentItem(item_x);
1169  }
1170  }
1171 
1172  if (!changedCommand) // on group name change set cursor on the group that has been changed
1173  {
1174  for(int i = 0; i < ui->commandTree->topLevelItemCount(); i++)
1175  {
1176  QTreeWidgetItem* item = ui->commandTree->topLevelItem(i);
1177 
1178  if (item->text(0) == newGroupName) {
1179  ui->commandTree->setCurrentItem(item);
1180  }
1181  }
1182  }
1183  }
1184 }
1185 
1187 {
1188  QTreeWidgetItem* item = ui->commandTree->currentItem();
1189 
1190  if (item != 0)
1191  {
1192  if (item->type() == PItem) // delete individual command
1193  {
1194  const Command* command = qvariant_cast<const Command*>(item->data(0, Qt::UserRole));
1195 
1196  if(command)
1197  {
1198  if (QMessageBox::question(this,
1199  tr("Delete command"),
1200  tr("Do you want to delete command '%1'?")
1201  .arg(command->getDescription()), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
1202  {
1203  delete item;
1204  m_settings.deleteCommand(command);
1205  }
1206  }
1207  }
1208  else if (item->type() == PGroup) // delete all commands in this group
1209  {
1210  if (QMessageBox::question(this,
1211  tr("Delete command group"),
1212  tr("Do you want to delete command group '%1'?")
1213  .arg(item->text(0)), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
1214  {
1215  m_settings.deleteCommandGroup(item->text(0));
1216 
1217  ui->commandTree->clear();
1218 
1219  for (int i = 0; i < m_settings.getCommandCount(); ++i) {
1221  }
1222  }
1223  }
1224  }
1225 }
1226 
1228 {
1229  QTreeWidgetItem* item = ui->commandTree->currentItem();
1230 
1231  if (item != 0)
1232  {
1233  int currentDeviceSetIndex = ui->tabInputsSelect->currentIndex();
1234 
1235  if (item->type() == PItem) // run individual command
1236  {
1237  const Command* command = qvariant_cast<const Command*>(item->data(0, Qt::UserRole));
1238  Command* command_mod = const_cast<Command*>(command);
1239  command_mod->run(m_apiServer->getHost(), m_apiServer->getPort(), currentDeviceSetIndex);
1240  }
1241  else if (item->type() == PGroup) // run all commands in this group
1242  {
1243  QString group = item->text(0);
1244 
1245  for (int i = 0; i < m_settings.getCommandCount(); ++i)
1246  {
1247  Command *command_mod = const_cast<Command*>(m_settings.getCommand(i));
1248 
1249  if (command_mod->getGroup() == group) {
1250  command_mod->run(m_apiServer->getHost(), m_apiServer->getPort(), currentDeviceSetIndex);
1251  }
1252  }
1253  }
1254  }
1255 }
1256 
1258 {
1259  QTreeWidgetItem* item = ui->commandTree->currentItem();
1260 
1261  if ((item != 0) && (item->type() == PItem))
1262  {
1263  const Command* command = qvariant_cast<const Command*>(item->data(0, Qt::UserRole));
1264  Command* command_mod = const_cast<Command*>(command);
1265  CommandOutputDialog commandOutputDialog(*command_mod);
1266  commandOutputDialog.exec();
1267  }
1268 }
1269 
1271 {
1273  m_settings.save();
1274 }
1275 
1276 void MainWindow::commandKeysConnect(QObject *object, const char *slot)
1277 {
1278  setFocus();
1279  connect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)),
1280  object, slot);
1281 }
1282 
1283 void MainWindow::commandKeysDisconnect(QObject *object, const char *slot)
1284 {
1285  disconnect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)),
1286  object, slot);
1287 }
1288 
1290 {
1291  qDebug("on_commandKeyboardConnect_toggled: %s", checked ? "true" : "false");
1292 
1293  if (checked)
1294  {
1295  commandKeysConnect(this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool)));
1296  }
1297  else
1298  {
1299  commandKeysDisconnect(this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool)));
1300  }
1301 }
1302 
1304 {
1305  QStringList groups;
1306  QString group;
1307  QString description = "";
1308 
1309  for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++) {
1310  groups.append(ui->presetTree->topLevelItem(i)->text(0));
1311  }
1312 
1313  QTreeWidgetItem* item = ui->presetTree->currentItem();
1314 
1315  if(item != 0)
1316  {
1317  if(item->type() == PGroup) {
1318  group = item->text(0);
1319  } else if(item->type() == PItem) {
1320  group = item->parent()->text(0);
1321  description = item->text(0);
1322  }
1323  }
1324 
1325  AddPresetDialog dlg(groups, group, this);
1326 
1327  if (description.length() > 0) {
1328  dlg.setDescription(description);
1329  }
1330 
1331  if(dlg.exec() == QDialog::Accepted) {
1332  Preset* preset = m_settings.newPreset(dlg.group(), dlg.description());
1333  savePresetSettings(preset, ui->tabInputsView->currentIndex());
1334 
1335  ui->presetTree->setCurrentItem(addPresetToTree(preset));
1336  }
1337 
1339 }
1340 
1342 {
1343  QTreeWidgetItem* item = ui->presetTree->currentItem();
1344  const Preset* changedPreset = 0;
1345 
1346  if(item != 0)
1347  {
1348  if(item->type() == PItem)
1349  {
1350  const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
1351 
1352  if (preset != 0)
1353  {
1354  Preset* preset_mod = const_cast<Preset*>(preset);
1355  savePresetSettings(preset_mod, ui->tabInputsView->currentIndex());
1356  changedPreset = preset;
1357  }
1358  }
1359  }
1360 
1362  ui->presetTree->clear();
1363 
1364  for (int i = 0; i < m_settings.getPresetCount(); ++i)
1365  {
1366  QTreeWidgetItem *item_x = addPresetToTree(m_settings.getPreset(i));
1367  const Preset* preset_x = qvariant_cast<const Preset*>(item_x->data(0, Qt::UserRole));
1368  if (changedPreset && (preset_x == changedPreset)) { // set cursor on changed preset
1369  ui->presetTree->setCurrentItem(item_x);
1370  }
1371  }
1372 }
1373 
1375 {
1376  QTreeWidgetItem* item = ui->presetTree->currentItem();
1377  QStringList groups;
1378  bool change = false;
1379  const Preset *changedPreset = 0;
1380  QString newGroupName;
1381 
1382  for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++) {
1383  groups.append(ui->presetTree->topLevelItem(i)->text(0));
1384  }
1385 
1386  if(item != 0)
1387  {
1388  if (item->type() == PItem)
1389  {
1390  const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
1391  AddPresetDialog dlg(groups, preset->getGroup(), this);
1392  dlg.setDescription(preset->getDescription());
1393 
1394  if (dlg.exec() == QDialog::Accepted)
1395  {
1396  Preset* preset_mod = const_cast<Preset*>(preset);
1397  preset_mod->setGroup(dlg.group());
1398  preset_mod->setDescription(dlg.description());
1399  change = true;
1400  changedPreset = preset;
1401  }
1402  }
1403  else if (item->type() == PGroup)
1404  {
1405  AddPresetDialog dlg(groups, item->text(0), this);
1406  dlg.showGroupOnly();
1407  dlg.setDialogTitle("Edit preset group");
1408 
1409  if (dlg.exec() == QDialog::Accepted)
1410  {
1411  m_settings.renamePresetGroup(item->text(0), dlg.group());
1412  newGroupName = dlg.group();
1413  change = true;
1414  }
1415  }
1416  }
1417 
1418  if (change)
1419  {
1421  ui->presetTree->clear();
1422 
1423  for (int i = 0; i < m_settings.getPresetCount(); ++i)
1424  {
1425  QTreeWidgetItem *item_x = addPresetToTree(m_settings.getPreset(i));
1426  const Preset* preset_x = qvariant_cast<const Preset*>(item_x->data(0, Qt::UserRole));
1427  if (changedPreset && (preset_x == changedPreset)) { // set cursor on changed preset
1428  ui->presetTree->setCurrentItem(item_x);
1429  }
1430  }
1431 
1432  if (!changedPreset) // on group name change set cursor on the group that has been changed
1433  {
1434  for(int i = 0; i < ui->presetTree->topLevelItemCount(); i++)
1435  {
1436  QTreeWidgetItem* item = ui->presetTree->topLevelItem(i);
1437 
1438  if (item->text(0) == newGroupName) {
1439  ui->presetTree->setCurrentItem(item);
1440  }
1441  }
1442  }
1443  }
1444 }
1445 
1447 {
1448  QTreeWidgetItem* item = ui->presetTree->currentItem();
1449 
1450  if(item != 0) {
1451  if(item->type() == PItem)
1452  {
1453  const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
1454  QString base64Str = preset->serialize().toBase64();
1455  QString fileName = QFileDialog::getSaveFileName(this,
1456  tr("Open preset export file"), ".", tr("Preset export files (*.prex)"), 0, QFileDialog::DontUseNativeDialog);
1457 
1458  if (fileName != "")
1459  {
1460  QFileInfo fileInfo(fileName);
1461 
1462  if (fileInfo.suffix() != "prex") {
1463  fileName += ".prex";
1464  }
1465 
1466  QFile exportFile(fileName);
1467 
1468  if (exportFile.open(QIODevice::WriteOnly | QIODevice::Text))
1469  {
1470  QTextStream outstream(&exportFile);
1471  outstream << base64Str;
1472  exportFile.close();
1473  }
1474  else
1475  {
1476  QMessageBox::information(this, tr("Message"), tr("Cannot open file for writing"));
1477  }
1478  }
1479  }
1480  }
1481 }
1482 
1484 {
1485  QTreeWidgetItem* item = ui->presetTree->currentItem();
1486 
1487  if(item != 0)
1488  {
1489  QString group;
1490 
1491  if (item->type() == PGroup) {
1492  group = item->text(0);
1493  } else if (item->type() == PItem) {
1494  group = item->parent()->text(0);
1495  } else {
1496  return;
1497  }
1498 
1499  QString fileName = QFileDialog::getOpenFileName(this,
1500  tr("Open preset export file"), ".", tr("Preset export files (*.prex)"), 0, QFileDialog::DontUseNativeDialog);
1501 
1502  if (fileName != "")
1503  {
1504  QFile exportFile(fileName);
1505 
1506  if (exportFile.open(QIODevice::ReadOnly | QIODevice::Text))
1507  {
1508  QByteArray base64Str;
1509  QTextStream instream(&exportFile);
1510  instream >> base64Str;
1511  exportFile.close();
1512 
1513  Preset* preset = m_settings.newPreset("", "");
1514  preset->deserialize(QByteArray::fromBase64(base64Str));
1515  preset->setGroup(group); // override with current group
1516 
1517  ui->presetTree->setCurrentItem(addPresetToTree(preset));
1518  }
1519  else
1520  {
1521  QMessageBox::information(this, tr("Message"), tr("Cannot open file for reading"));
1522  }
1523  }
1524  }
1525 }
1526 
1528 {
1529  savePresetSettings(m_settings.getWorkingPreset(), ui->tabInputsView->currentIndex());
1530  m_settings.save();
1531 }
1532 
1534 {
1535  qDebug() << "MainWindow::on_presetLoad_clicked";
1536 
1537  QTreeWidgetItem* item = ui->presetTree->currentItem();
1538 
1539  if(item == 0)
1540  {
1541  qDebug("MainWindow::on_presetLoad_clicked: item null");
1543  return;
1544  }
1545 
1546  const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
1547 
1548  if(preset == 0)
1549  {
1550  qDebug("MainWindow::on_presetLoad_clicked: preset null");
1551  return;
1552  }
1553 
1554  loadPresetSettings(preset, ui->tabInputsView->currentIndex());
1555  applySettings();
1556 }
1557 
1559 {
1560  QTreeWidgetItem* item = ui->presetTree->currentItem();
1561 
1562  if (item == 0)
1563  {
1565  return;
1566  }
1567  else
1568  {
1569  if (item->type() == PItem)
1570  {
1571  const Preset* preset = qvariant_cast<const Preset*>(item->data(0, Qt::UserRole));
1572 
1573  if (preset)
1574  {
1575  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) {
1576  delete item;
1577  m_settings.deletePreset(preset);
1578  }
1579  }
1580  }
1581  else if (item->type() == PGroup)
1582  {
1583  if (QMessageBox::question(this,
1584  tr("Delete preset group"),
1585  tr("Do you want to delete preset group '%1'?")
1586  .arg(item->text(0)), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
1587  {
1588  m_settings.deletePresetGroup(item->text(0));
1589 
1590  ui->presetTree->clear();
1591 
1592  for (int i = 0; i < m_settings.getPresetCount(); ++i) {
1594  }
1595  }
1596  }
1597  }
1598 }
1599 
1600 void MainWindow::on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
1601 {
1602  (void) current;
1603  (void) previous;
1605 }
1606 
1607 void MainWindow::on_presetTree_itemActivated(QTreeWidgetItem *item, int column)
1608 {
1609  (void) item;
1610  (void) column;
1612 }
1613 
1615 {
1616  PluginsDialog pluginsDialog(m_pluginManager, this);
1617  pluginsDialog.exec();
1618 }
1619 
1621 {
1622  AudioDialogX audioDialog(m_dspEngine->getAudioDeviceManager(), this);
1623  audioDialog.exec();
1624 }
1625 
1627 {
1628  LoggingDialog loggingDialog(m_settings, this);
1629  loggingDialog.exec();
1631 }
1632 
1634 {
1635  MyPositionDialog myPositionDialog(m_settings, this);
1636  myPositionDialog.exec();
1637 }
1638 
1640 {
1641  qDebug("MainWindow::on_action_DeviceUserArguments_triggered");
1643  deviceUserArgsDialog.exec();
1644 }
1645 
1647 {
1648  qDebug("MainWindow::on_action_AMBE_triggered");
1649  AMBEDevicesDialog ambeDevicesDialog(m_dspEngine->getAMBEEngine(), this);
1650  ambeDevicesDialog.exec();
1651 }
1652 
1654 {
1655  // Do it in the currently selected source tab
1656  int currentSourceTabIndex = ui->tabInputsSelect->currentIndex();
1657 
1658  if (currentSourceTabIndex >= 0)
1659  {
1660  qDebug("MainWindow::sampleSourceChanged: tab at %d", currentSourceTabIndex);
1661  DeviceUISet *deviceUI = m_deviceUIs[currentSourceTabIndex];
1662  deviceUI->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings
1663  deviceUI->m_deviceAPI->stopDeviceEngine();
1664 
1665  // deletes old UI and input object
1666  deviceUI->m_deviceAPI->getSampleSource()->setMessageQueueToGUI(0); // have source stop sending messages to the GUI
1669  deviceUI->m_deviceAPI->resetSamplingDeviceId();
1671  deviceUI->m_deviceAPI->getSampleSource());
1672  deviceUI->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
1673 
1676  deviceUI->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
1677  deviceUI->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
1678  deviceUI->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
1679  deviceUI->m_deviceAPI->setHardwareId(samplingDevice->hardwareId);
1680  deviceUI->m_deviceAPI->setSamplingDeviceId(samplingDevice->id);
1681  deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial);
1682  deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
1684 
1685  QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence);
1686 
1687  if (userArgs.size() > 0) {
1688  deviceUI->m_deviceAPI->setHardwareUserArguments(userArgs);
1689  }
1690 
1691  // add to buddies list
1692  std::vector<DeviceUISet*>::iterator it = m_deviceUIs.begin();
1693  int nbOfBuddies = 0;
1694 
1695  for (; it != m_deviceUIs.end(); ++it)
1696  {
1697  if (*it != deviceUI) // do not add to itself
1698  {
1699  if ((*it)->m_deviceSourceEngine) // it is a source device
1700  {
1701  if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) &&
1702  (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial()))
1703  {
1704  (*it)->m_deviceAPI->addSourceBuddy(deviceUI->m_deviceAPI);
1705  nbOfBuddies++;
1706  }
1707  }
1708 
1709  if ((*it)->m_deviceSinkEngine) // it is a sink device
1710  {
1711  if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) &&
1712  (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial()))
1713  {
1714  (*it)->m_deviceAPI->addSourceBuddy(deviceUI->m_deviceAPI);
1715  nbOfBuddies++;
1716  }
1717  }
1718  }
1719  }
1720 
1721  if (nbOfBuddies == 0) {
1722  deviceUI->m_deviceAPI->setBuddyLeader(true);
1723  }
1724 
1725  // constructs new GUI and input object
1727  deviceUI->m_deviceAPI->getSamplingDeviceId(), deviceUI->m_deviceAPI);
1728  deviceUI->m_deviceAPI->setSampleSource(source);
1729  QWidget *gui;
1731  deviceUI->m_deviceAPI->getSamplingDeviceId(),
1732  &gui,
1733  deviceUI);
1735  deviceUI->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginUI);
1736  setDeviceGUI(currentSourceTabIndex, gui, deviceUI->m_deviceAPI->getSamplingDeviceDisplayName());
1737  deviceUI->m_deviceAPI->getSampleSource()->init();
1738 
1739  deviceUI->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings
1740 
1741  if (currentSourceTabIndex == 0) // save as default starting device
1742  {
1743  m_settings.setSourceIndex(samplingDevice->sequence);
1744  m_settings.setSourceDeviceId(samplingDevice->id);
1745  }
1746  }
1747 }
1748 
1750 {
1751  // Do it in the currently selected source tab
1752  int currentSinkTabIndex = ui->tabInputsSelect->currentIndex();
1753 
1754  if (currentSinkTabIndex >= 0)
1755  {
1756  qDebug("MainWindow::sampleSinkChanged: tab at %d", currentSinkTabIndex);
1757  DeviceUISet *deviceUI = m_deviceUIs[currentSinkTabIndex];
1758  deviceUI->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings
1759  deviceUI->m_deviceAPI->stopDeviceEngine();
1760 
1761  // deletes old UI and output object
1762  deviceUI->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(0); // have sink stop sending messages to the GUI
1765  deviceUI->m_deviceAPI->resetSamplingDeviceId();
1767  deviceUI->m_deviceAPI->getSampleSink());
1768  deviceUI->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists
1769 
1771  deviceUI->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
1772  deviceUI->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
1773  deviceUI->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
1774  deviceUI->m_deviceAPI->setHardwareId(samplingDevice->hardwareId);
1775  deviceUI->m_deviceAPI->setSamplingDeviceId(samplingDevice->id);
1776  deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial);
1777  deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
1779 
1780  QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence);
1781 
1782  if (userArgs.size() > 0) {
1783  deviceUI->m_deviceAPI->setHardwareUserArguments(userArgs);
1784  }
1785 
1786  // add to buddies list
1787  std::vector<DeviceUISet*>::iterator it = m_deviceUIs.begin();
1788  int nbOfBuddies = 0;
1789 
1790  for (; it != m_deviceUIs.end(); ++it)
1791  {
1792  if (*it != deviceUI) // do not add to itself
1793  {
1794  if ((*it)->m_deviceSourceEngine) // it is a source device
1795  {
1796  if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) &&
1797  (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial()))
1798  {
1799  (*it)->m_deviceAPI->addSinkBuddy(deviceUI->m_deviceAPI);
1800  nbOfBuddies++;
1801  }
1802  }
1803 
1804  if ((*it)->m_deviceSinkEngine) // it is a sink device
1805  {
1806  if ((deviceUI->m_deviceAPI->getHardwareId() == (*it)->m_deviceAPI->getHardwareId()) &&
1807  (deviceUI->m_deviceAPI->getSamplingDeviceSerial() == (*it)->m_deviceAPI->getSamplingDeviceSerial()))
1808  {
1809  (*it)->m_deviceAPI->addSinkBuddy(deviceUI->m_deviceAPI);
1810  nbOfBuddies++;
1811  }
1812  }
1813  }
1814  }
1815 
1816  if (nbOfBuddies == 0) {
1817  deviceUI->m_deviceAPI->setBuddyLeader(true);
1818  }
1819 
1820  // constructs new GUI and output object
1822  deviceUI->m_deviceAPI->getSamplingDeviceId(), deviceUI->m_deviceAPI);
1823  deviceUI->m_deviceAPI->setSampleSink(sink);
1824  QWidget *gui;
1826  deviceUI->m_deviceAPI->getSamplingDeviceId(),
1827  &gui,
1828  deviceUI);
1830  deviceUI->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginUI);
1831  setDeviceGUI(currentSinkTabIndex, gui, deviceUI->m_deviceAPI->getSamplingDeviceDisplayName(), 1);
1832  m_deviceUIs.back()->m_deviceAPI->getSampleSink()->init();
1833 
1834  deviceUI->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings
1835  }
1836 }
1837 
1839 {
1840  // Do it in the currently selected source tab
1841  int currentMIMOTabIndex = ui->tabInputsSelect->currentIndex();
1842 
1843  if (currentMIMOTabIndex >= 0)
1844  {
1845  qDebug("MainWindow::sampleMIMOChanged: tab at %d", currentMIMOTabIndex);
1846  DeviceUISet *deviceUI = m_deviceUIs[currentMIMOTabIndex];
1847  deviceUI->m_deviceAPI->saveSamplingDeviceSettings(m_settings.getWorkingPreset()); // save old API settings
1848  deviceUI->m_deviceAPI->stopDeviceEngine();
1849 
1850  // deletes old UI and output object
1851  deviceUI->m_deviceAPI->getSampleMIMO()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI
1854  deviceUI->m_deviceAPI->resetSamplingDeviceId();
1856  deviceUI->m_deviceAPI->getSampleMIMO());
1857 
1860  deviceUI->m_deviceAPI->setSamplingDeviceSequence(samplingDevice->sequence);
1861  deviceUI->m_deviceAPI->setDeviceNbItems(samplingDevice->deviceNbItems);
1862  deviceUI->m_deviceAPI->setDeviceItemIndex(samplingDevice->deviceItemIndex);
1863  deviceUI->m_deviceAPI->setHardwareId(samplingDevice->hardwareId);
1864  deviceUI->m_deviceAPI->setSamplingDeviceId(samplingDevice->id);
1865  deviceUI->m_deviceAPI->setSamplingDeviceSerial(samplingDevice->serial);
1866  deviceUI->m_deviceAPI->setSamplingDeviceDisplayName(samplingDevice->displayedName);
1868  DeviceEnumerator::instance()->getMIMOPluginInterface(deviceUI->m_samplingDeviceControl->getSelectedDeviceIndex()));
1869 
1870  QString userArgs = m_settings.getDeviceUserArgs().findUserArgs(samplingDevice->hardwareId, samplingDevice->sequence);
1871 
1872  if (userArgs.size() > 0) {
1873  deviceUI->m_deviceAPI->setHardwareUserArguments(userArgs);
1874  }
1875 
1876  // constructs new GUI and MIMO object
1878  deviceUI->m_deviceAPI->getSamplingDeviceId(), deviceUI->m_deviceAPI);
1879  deviceUI->m_deviceAPI->setSampleMIMO(mimo);
1880  QWidget *gui;
1882  deviceUI->m_deviceAPI->getSamplingDeviceId(),
1883  &gui,
1884  deviceUI);
1886  deviceUI->m_deviceAPI->setSamplingDevicePluginInstanceGUI(pluginUI);
1887  setDeviceGUI(currentMIMOTabIndex, gui, deviceUI->m_deviceAPI->getSamplingDeviceDisplayName(), 2);
1888  m_deviceUIs.back()->m_deviceAPI->getSampleMIMO()->init();
1889 
1890  deviceUI->m_deviceAPI->loadSamplingDeviceSettings(m_settings.getWorkingPreset()); // load new API settings
1891  }
1892 }
1893 
1895 {
1896  (void) checked;
1897  // Do it in the currently selected source tab
1898  int currentSourceTabIndex = ui->tabInputsSelect->currentIndex();
1899 
1900  if (currentSourceTabIndex >= 0)
1901  {
1902  DeviceUISet *deviceUI = m_deviceUIs[currentSourceTabIndex];
1903 
1904  if (deviceUI->m_deviceSourceEngine) // source device => Rx channels
1905  {
1907  deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI, deviceUI->m_deviceAPI);
1908  }
1909  else if (deviceUI->m_deviceSinkEngine) // sink device => Tx channels
1910  {
1912  deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex(), deviceUI, deviceUI->m_deviceAPI);
1913  }
1914  else if (deviceUI->m_deviceMIMOEngine) // MIMO device => all possible channels. Depends on index range
1915  {
1916  int nbRxChannels = deviceUI->getNumberOfAvailableRxChannels();
1917  int nbTxChannels = deviceUI->getNumberOfAvailableTxChannels();
1918  int selectedIndex = deviceUI->m_samplingDeviceControl->getChannelSelector()->currentIndex();
1919  qDebug("MainWindow::channelAddClicked: MIMO: tab: %d nbRx: %d nbTx: %d selected: %d",
1920  currentSourceTabIndex, nbRxChannels, nbTxChannels, selectedIndex);
1921 
1922  if (selectedIndex < nbRxChannels) {
1924  selectedIndex, deviceUI, deviceUI->m_deviceAPI);
1925  } else if (selectedIndex < nbRxChannels + nbTxChannels) {
1927  selectedIndex - nbRxChannels, deviceUI, deviceUI->m_deviceAPI);
1928  }
1929  }
1930  }
1931 }
1932 
1934 {
1936  dlg.exec();
1937 }
1938 
1940 {
1941  addSourceDevice(-1); // create with file source device by default
1942 }
1943 
1945 {
1946  addSinkDevice();
1947 }
1948 
1950 {
1951  if (m_dspEngine->getMIMOSupport()) {
1952  addMIMODevice();
1953  } else {
1954  QMessageBox::information(this, tr("Message"), tr("MIMO operation not supported yet"));
1955  }
1956 }
1957 
1959 {
1960  if (m_deviceUIs.size() > 1)
1961  {
1962  removeLastDevice();
1963  }
1964 }
1965 
1967 {
1968  int inputViewIndex = ui->tabInputsView->currentIndex();
1969 
1970  if ((inputViewIndex >= 0) && (m_masterTabIndex >= 0) && (inputViewIndex != m_masterTabIndex))
1971  {
1972  DeviceUISet *deviceUI = m_deviceUIs[inputViewIndex];
1973  DeviceUISet *lastdeviceUI = m_deviceUIs[m_masterTabIndex];
1974  lastdeviceUI->m_mainWindowState = saveState();
1975  restoreState(deviceUI->m_mainWindowState);
1976  m_masterTabIndex = inputViewIndex;
1977  }
1978 
1979  ui->tabSpectra->setCurrentIndex(inputViewIndex);
1980  ui->tabChannels->setCurrentIndex(inputViewIndex);
1981  ui->tabInputsSelect->setCurrentIndex(inputViewIndex);
1982  ui->tabSpectraGUI->setCurrentIndex(inputViewIndex);
1983 }
1984 
1986 {
1987  m_dateTimeWidget->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss t"));
1988 }
1989 
1991 {
1993 
1994  if (m_settings.getUseLogFile())
1995  {
1996  qtwebapp::FileLoggerSettings fileLoggerSettings; // default values
1997 
1998  if (m_logger->hasFileLogger()) {
1999  fileLoggerSettings = m_logger->getFileLoggerSettings(); // values from file logger if it exists
2000  }
2001 
2002  fileLoggerSettings.fileName = m_settings.getLogFileName(); // put new values
2003  m_logger->createOrSetFileLogger(fileLoggerSettings, 2000); // create file logger if it does not exist and apply settings in any case
2004  }
2005 
2006  if (m_logger->hasFileLogger()) {
2008  }
2009 
2011 
2012  if (m_settings.getUseLogFile())
2013  {
2014 #if QT_VERSION >= 0x050400
2015  QString appInfoStr(tr("%1 %2 Qt %3 %4b %5 %6 DSP Rx:%7b Tx:%8b PID %9")
2016  .arg(qApp->applicationName())
2017  .arg(qApp->applicationVersion())
2018  .arg(QT_VERSION_STR)
2019  .arg(QT_POINTER_SIZE*8)
2020  .arg(QSysInfo::currentCpuArchitecture())
2021  .arg(QSysInfo::prettyProductName())
2022  .arg(SDR_RX_SAMP_SZ)
2023  .arg(SDR_TX_SAMP_SZ)
2024  .arg(qApp->applicationPid()));
2025 #else
2026  QString appInfoStr(tr("%1 %2 Qt %3 %4b DSP Rx:%5b Tx:%6b PID %7")
2027  .arg(qApp->applicationName())
2028  .arg(qApp->applicationVersion())
2029  .arg(QT_VERSION_STR)
2030  .arg(QT_POINTER_SIZE*8)
2031  .arg(SDR_RX_SAMP_SZ)
2032  .arg(SDR_TX_SAMP_SZ)
2033  .arg(qApp->applicationPid()));
2034  #endif
2035  m_logger->logToFile(QtInfoMsg, appInfoStr);
2036  }
2037 }
2038 
2039 void MainWindow::commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release)
2040 {
2041  //qDebug("MainWindow::commandKeyPressed: key: %x mod: %x %s", (int) key, (int) keyModifiers, release ? "release" : "press");
2042  int currentDeviceSetIndex = ui->tabInputsSelect->currentIndex();
2043 
2044  for (int i = 0; i < m_settings.getCommandCount(); ++i)
2045  {
2046  const Command* command = m_settings.getCommand(i);
2047 
2048  if (command->getAssociateKey()
2049  && (command->getRelease() == release)
2050  && (command->getKey() == key)
2051  && (command->getKeyModifiers() == keyModifiers))
2052  {
2053  Command* command_mod = const_cast<Command*>(command);
2054  command_mod->run(m_apiServer->getHost(), m_apiServer->getPort(), currentDeviceSetIndex);
2055  }
2056  }
2057 }
MessageQueue m_inputMessageQueue
Definition: mainwindow.h:306
void clearChannels()
Definition: preset.h:84
void setSampleMIMO(DeviceSampleMIMO *mimo)
Set the device sample MIMO.
Definition: deviceapi.cpp:206
void loadSettings()
Definition: mainwindow.cpp:708
May expose any number of input and/or output streams.
Definition: deviceapi.h:49
void on_presetExport_clicked()
void updatePresetControls()
Definition: mainwindow.cpp:830
DSPEngine * m_dspEngine
Definition: mainwindow.h:312
void setHardwareId(const QString &id)
Definition: deviceapi.cpp:364
void setBuddyLeader(bool isBuddyLeader)
Definition: deviceapi.h:164
void listRxChannels(QList< QString > &list)
const QString & getLogFileName() const
Definition: mainsettings.h:65
void setUseFileLogger(bool use)
void on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
int getFileSinkDeviceIndex() const
Get Tx default device.
GLSpectrumGUI * m_spectrumGUI
Definition: deviceuiset.h:45
void commandKeysConnect(QObject *object, const char *slot)
Message * pop()
Pop message from queue.
int getDeviceIndex() const
Definition: mainwindow.h:199
void loadTxChannelSettings(const Preset *preset, PluginAPI *pluginAPI)
virtual DeviceSampleSource * createSampleSourcePluginInstance(const QString &sourceId, DeviceAPI *deviceAPI)
int sequence
The device sequence. >0 when more than one device of the same type is connected.
void removeLastDeviceMIMOEngine()
Definition: dspengine.cpp:99
Ui::MainWindow * ui
Definition: mainwindow.h:305
virtual void init()=0
initializations to be done when all collaborating objects are created and possibly connected ...
void setSampleSource(DeviceSampleSource *source)
Set the device sample source (single Rx)
Definition: deviceapi.cpp:192
Qt::KeyboardModifiers getKeyModifiers() const
Definition: command.h:54
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
Definition: deviceapi.cpp:266
int getSourceIndex() const
Definition: mainsettings.h:48
QString displayedName
The human readable name.
void on_commandKeyboardConnect_toggled(bool checked)
void addChannelRollup(int deviceTabIndex, QWidget *widget)
Definition: mainwindow.cpp:660
void sampleMIMOChanged()
bool handleMessage(const Message &cmd)
Definition: mainwindow.cpp:925
void addCommand(Command *command)
void setMessageRect(QRect rect, int alignment=Qt::AlignLeft)
void setSamplingDevicePluginInstanceGUI(PluginInstanceGUI *gui)
Definition: deviceapi.cpp:384
int getDeviceSetIndex() const
Definition: mainwindow.h:224
DeviceSampleSource * getSampleSource()
Return pointer to the device sample source (single Rx) or nullptr.
Definition: deviceapi.cpp:213
std::vector< DeviceUISet * > m_deviceUIs
Definition: mainwindow.h:308
WebAPIRequestMapper * m_requestMapper
Definition: mainwindow.h:330
void createOrSetFileLogger(const FileLoggerSettings &settings, const int refreshInterval=10000)
void setLayout(const QByteArray &data)
Definition: preset.h:81
int getChannelRegistrationIndex() const
Definition: mainwindow.h:225
const QString & getDescription() const
Definition: command.h:50
quint64 getCenterFrequency() const
Definition: preset.h:76
DSPDeviceSourceEngine * addDeviceSourceEngine()
Definition: dspengine.cpp:56
QTreeWidgetItem * addPresetToTree(const Preset *preset)
Definition: mainwindow.cpp:846
void setLoggingOptions()
Qt::Key getKey() const
Definition: command.h:52
void loadPlugins(const QString &pluginsSubDir)
bool getMIMOSupport() const
Definition: mainparser.h:37
void saveTxChannelSettings(Preset *preset)
void on_presetDelete_clicked()
void setDescription(const QString &description)
bool getUseLogFile() const
Definition: mainsettings.h:64
Exposes a single output stream that can be one of the streams of a physical device.
Definition: deviceapi.h:48
virtual DeviceSampleMIMO * createSampleMIMOPluginInstance(const QString &mimoId, DeviceAPI *deviceAPI)
void toCommand(Command &command) const
virtual PluginInstanceGUI * createSampleSinkPluginInstanceGUI(const QString &sinkId, QWidget **widget, DeviceUISet *deviceUISet)
void removeSpectrumSink(BasebandSampleSink *spectrumSink)
Add a spectrum vis baseband sample sink.
void removeSink(BasebandSampleSink *sink)
Remove a sample sink.
void deleteCommand(const Command *command)
void addViewAction(QAction *action)
Definition: mainwindow.cpp:671
QString hardwareId
The internal id that identifies the type of hardware (i.e. HackRF, BladeRF, ...)
void setAdapter(WebAPIAdapterInterface *adapter)
void sortCommands()
void stop()
This thread stop.
DSPDeviceSinkEngine * addDeviceSinkEngine()
Definition: dspengine.cpp:74
const Command * getCommand(int index) const
Definition: mainsettings.h:40
void on_action_addMIMODevice_triggered()
void on_commandRun_clicked()
qtwebapp::LoggerWithFile * m_logger
Definition: mainwindow.h:328
bool isSourcePreset() const
Definition: preset.h:66
virtual MessageQueue * getInputMessageQueue()=0
void on_action_AMBE_triggered()
void loadPresetSettings(const Preset *preset, int tabIndex)
Definition: mainwindow.cpp:736
void start()
This thread start.
int getRxSamplingDeviceIndex(const QString &deviceId, int sequence)
void stopProcess()
Stop process sequence.
void setSamplingDeviceSequence(int sequence)
Definition: deviceapi.h:114
QString getKeyLabel() const
Definition: command.cpp:144
void applySettings()
Definition: mainwindow.cpp:921
void on_settingsSave_clicked()
FileLoggerSettings getFileLoggerSettings() const
void closeEvent(QCloseEvent *)
Definition: mainwindow.cpp:815
bool getMIMOSupport() const
Definition: dspengine.h:86
DeviceSampleSink * getSampleSink()
Return pointer to the device sample sink (single Tx) or nullptr.
Definition: deviceapi.cpp:222
void sortPresets()
Preset * newPreset(const QString &group, const QString &description)
Exposes a single input stream that can be one of the streams of a physical device.
Definition: deviceapi.h:47
int getNumberOfAvailableRxChannels() const
Definition: deviceuiset.h:80
DSPDeviceSourceEngine * m_deviceSourceEngine
Definition: deviceuiset.h:49
Preset * getPreset() const
Definition: mainwindow.h:117
void on_presetSave_clicked()
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void setSamplingDeviceId(const QString &id)
Definition: deviceapi.h:110
CommandKeyReceiver * m_commandKeyReceiver
Definition: mainwindow.h:336
void on_commandDuplicate_clicked()
void stopGeneration()
Stop generation sequence.
void run(const QString &apiAddress, int apiPort, int deviceSetIndex)
Definition: command.cpp:162
void setSamplingDeviceDisplayName(const QString &name)
Definition: deviceapi.h:113
void commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release)
void on_commandDelete_clicked()
#define SDR_RX_SAMP_SZ
Definition: dsptypes.h:32
const PluginInterface::SamplingDevice * getMIMOSamplingDevice(int deviceIndex) const
void sampleSinkChanged()
void on_action_View_Fullscreen_toggled(bool checked)
DeviceAPI * m_deviceAPI
Definition: deviceuiset.h:48
const QByteArray & getLayout() const
Definition: preset.h:82
void renamePresetGroup(const QString &oldGroupName, const QString &newGroupName)
SamplingDeviceControl * m_samplingDeviceControl
Definition: deviceuiset.h:47
int getPresetCount() const
Definition: mainsettings.h:30
void on_presetTree_itemActivated(QTreeWidgetItem *item, int column)
QList< DeviceWidgetTabData > m_deviceWidgetTabs
Definition: mainwindow.h:309
void loadRxChannelSettings(const Preset *preset, PluginAPI *pluginAPI)
virtual void deleteSampleMIMOPluginInstanceMIMO(DeviceSampleMIMO *mimo)
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
Definition: message.h:52
void setSpectrumConfig(const QByteArray &data)
Definition: preset.h:78
AMBEEngine * getAMBEEngine()
Definition: dspengine.h:56
const QString & getSamplingDeviceId() const
Definition: deviceapi.h:120
int getDeviceSetIndex() const
Definition: mainwindow.h:95
void tabInputViewIndexChanged()
void saveRxChannelSettings(Preset *preset)
void removeSpectrumSink(BasebandSampleSink *spectrumSink)
Add a spectrum vis baseband sample sink.
void addRollupWidget(QWidget *rollupWidget)
void on_presetUpdate_clicked()
int getDeviceSetIndex() const
Definition: mainwindow.h:198
void addMIMODevice()
Definition: mainwindow.cpp:425
void setDeviceGUI(int deviceTabIndex, QWidget *gui, const QString &deviceDisplayName, int deviceType=0)
Definition: mainwindow.cpp:676
void removeLastDeviceSinkEngine()
Definition: dspengine.cpp:81
QtMsgType getFileMinLogLevel() const
Definition: mainsettings.h:63
void createRxChannelInstance(int channelPluginIndex, DeviceUISet *deviceUISet, DeviceAPI *deviceAPI)
WebAPIServer * m_apiServer
Definition: mainwindow.h:331
void removeLastDevice()
Definition: mainwindow.cpp:512
void saveSamplingDeviceSettings(Preset *preset)
Definition: deviceapi.cpp:569
int deviceNbItems
Number of items (or streams) in the device. >1 for composite devices.
void deleteCommandGroup(const QString &groupName)
const QByteArray & getSpectrumConfig() const
Definition: preset.h:79
QByteArray serialize() const
Definition: preset.cpp:43
Definition: preset.h:28
void setDescription(const QString &description)
Definition: preset.h:73
void on_action_addSinkDevice_triggered()
WebAPIAdapterGUI * m_apiAdapter
Definition: mainwindow.h:332
Preset * getWorkingPreset()
Definition: mainsettings.h:47
void setConsoleMinMessageLevel(const QtMsgType &msgLevel)
uint32_t getUID() const
virtual PluginInstanceGUI * createSampleMIMOPluginInstanceGUI(const QString &mimoId, QWidget **widget, DeviceUISet *deviceUISet)
virtual PluginInstanceGUI * createSampleSourcePluginInstanceGUI(const QString &sourceId, QWidget **widget, DeviceUISet *deviceUISet)
void setDescription(const QString &description)
Definition: command.h:49
void removeLastDeviceSourceEngine()
Definition: dspengine.cpp:63
int32_t i
Definition: decimators.h:244
ChannelWindow * m_channelWindow
Definition: deviceuiset.h:46
PluginAPI * getPluginAPI()
Definition: pluginmanager.h:58
const QString & getHost() const
Definition: webapiserver.h:43
void stopAcquistion()
Stop acquisition sequence.
void on_action_My_Position_triggered()
void setAMBEEngine(AMBEEngine *ambeEngine)
Definition: mainsettings.h:70
void setGroup(const QString &group)
Definition: preset.h:71
static bool match(const Message *message)
Definition: message.cpp:45
void createStatusBar()
Definition: mainwindow.cpp:799
void stop()
This thread stop.
void on_commandsSave_clicked()
void on_action_DeviceUserArguments_triggered()
virtual void setMessageQueueToGUI(MessageQueue *queue)=0
void addSourceDevice(int deviceIndex)
Definition: mainwindow.cpp:267
void deletePreset(const Preset *preset)
void setSourcePreset(bool isSourcePreset)
Definition: preset.h:65
QString description() const
int getTestMIMODeviceIndex() const
Get MIMO default device.
void on_presetLoad_clicked()
virtual DeviceSampleSink * createSampleSinkPluginInstance(const QString &sinkId, DeviceAPI *deviceAPI)
#define SDR_TX_SAMP_SZ
Definition: dsptypes.h:38
void setMIMOSupport(bool mimoSupport)
Definition: dspengine.h:85
void sampleSourceChanged()
void addSink(BasebandSampleSink *sink)
Add a sample sink.
const QString & getSourceDeviceId() const
Definition: mainsettings.h:50
void setRelease(bool release)
DSPDeviceSinkEngine * m_deviceSinkEngine
Definition: deviceuiset.h:50
QString id
The internal plugin ID corresponding to the device (i.e. for HackRF input, for HackRF output ...
void logToFile(const QtMsgType type, const QString &message, const QString &file="", const QString &function="", const int line=0)
void clearBuddiesLists()
Definition: deviceapi.cpp:740
static MainWindow * m_instance
Definition: mainwindow.h:304
int getDeviceType() const
Definition: mainwindow.h:200
void listTxChannels(QList< QString > &list)
const Preset * getPreset(int index) const
Definition: mainsettings.h:31
QString serial
The device serial number defined by the vendor or a fake one (SDRplay)
QByteArray m_mainWindowState
Definition: deviceuiset.h:52
void createTxChannelInstance(int channelPluginIndex, DeviceUISet *deviceUISet, DeviceAPI *deviceAPI)
virtual void deleteSampleSinkPluginInstanceOutput(DeviceSampleSink *sink)
virtual QByteArray serialize() const
const QString & getSamplingDeviceSerial() const
Definition: deviceapi.h:121
PluginInterface * getPluginInterface()
Definition: deviceapi.h:132
friend class WebAPIAdapterGUI
Definition: mainwindow.h:87
AudioDeviceManager * getAudioDeviceManager()
Definition: dspengine.h:55
void showStatusMessage(const QString &message, const QColor &color=Qt::black)
void addSpectrumSink(BasebandSampleSink *spectrumSink)
Add a spectrum vis baseband sample sink.
void on_commandOutput_clicked()
const Preset * getPreset() const
Definition: mainwindow.h:143
virtual void deleteSampleSourcePluginInstanceGUI(PluginInstanceGUI *ui)
int getPort() const
Definition: webapiserver.h:44
MainSettings m_settings
Definition: mainwindow.h:307
const PluginInterface::SamplingDevice * getTxSamplingDevice(int deviceIndex) const
void commandKeysDisconnect(QObject *object, const char *slot)
virtual void setMessageQueueToGUI(MessageQueue *queue)=0
void setAudioDeviceManager(AudioDeviceManager *audioDeviceManager)
Definition: mainsettings.h:69
void deleteTxChannel(int channelIndex)
PluginInstanceGUI * getSamplingDevicePluginInstanceGUI()
Definition: deviceapi.h:134
void start()
This thread start.
QTimer m_statusTimer
Definition: mainwindow.h:316
const QString & getHardwareId() const
Definition: deviceapi.h:119
const QString & getGroup() const
Definition: command.h:48
void on_action_About_triggered()
void on_presetEdit_clicked()
void start()
This thread start.
void savePresetSettings(Preset *preset, int tabIndex)
Definition: mainwindow.cpp:766
DeviceUserArgs & getDeviceUserArgs()
Definition: mainsettings.h:66
void setSamplingDeviceSerial(const QString &serial)
Definition: deviceapi.h:112
void on_action_addSourceDevice_triggered()
void deletePresetGroup(const QString &groupName)
virtual const char * getIdentifier() const
Definition: message.cpp:35
bool deserialize(const QByteArray &data)
Definition: preset.cpp:94
void save() const
const PluginInterface::SamplingDevice * getRxSamplingDevice(int deviceIndex) const
virtual void deleteSampleMIMOPluginInstanceGUI(PluginInstanceGUI *ui)
void fromCommand(const Command &command)
void on_action_Loaded_Plugins_triggered()
virtual void deleteSampleSourcePluginInstanceInput(DeviceSampleSource *source)
DSPDeviceMIMOEngine * addDeviceMIMOEngine()
Definition: dspengine.cpp:92
bool getAssociateKey() const
Definition: command.h:56
void setDeviceItemIndex(uint32_t index)
Definition: deviceapi.cpp:374
QLabel * m_dateTimeWidget
Definition: mainwindow.h:319
QLabel * m_showSystemWidget
Definition: mainwindow.h:320
void channelAddClicked(bool checked)
const QString & getSamplingDeviceDisplayName() const
Definition: deviceapi.h:122
void setFileMinMessageLevel(const QtMsgType &msgLevel)
const Preset * getPreset() const
Definition: mainwindow.h:94
void on_commandNew_clicked()
void handleMessages()
QTreeWidgetItem * addCommandToTree(const Command *command)
Definition: mainwindow.cpp:883
void resetSamplingDeviceId()
Definition: deviceapi.h:111
void setGroup(const QString &group)
Definition: command.h:47
int getCommandCount() const
Definition: mainsettings.h:39
virtual void setMessageQueueToGUI(MessageQueue *queue)=0
void setSelectedDeviceIndex(int index)
void loadSamplingDeviceSettings(const Preset *preset)
Definition: deviceapi.cpp:481
QtMsgType getConsoleMinLogLevel() const
Definition: mainsettings.h:62
int getFileInputDeviceIndex() const
Get Rx default device.
const QString & getDescription() const
Definition: preset.h:74
void on_presetImport_clicked()
void deleteChannel(int deviceSetIndex, int channelIndex)
Definition: mainwindow.cpp:643
const QString & getServerAddress() const
Definition: mainparser.h:35
void setSamplingDevicePluginInterface(PluginInterface *iface)
Definition: deviceapi.cpp:379
QString m_apiHost
Definition: mainwindow.h:333
PluginManager * m_pluginManager
Definition: mainwindow.h:313
QTimer m_masterTimer
Definition: mainwindow.h:315
int m_apiPort
Definition: mainwindow.h:334
static DeviceEnumerator * instance()
void on_action_removeLastDevice_triggered()
void updateStatus()
int deviceItemIndex
For composite devices this is the Rx or Tx stream index. -1 if not initialized.
DeviceSampleMIMO * getSampleMIMO()
Return pointer to the device sample MIMO or nullptr.
Definition: deviceapi.cpp:231
void on_commandEdit_clicked()
void setDeviceNbItems(uint32_t nbItems)
Definition: deviceapi.cpp:369
void setSampleSink(DeviceSampleSink *sink)
Set the device sample sink (single Tx)
Definition: deviceapi.cpp:199
uint16_t getServerPort() const
Definition: mainparser.h:36
void on_action_Audio_triggered()
int getNumberOfAvailableTxChannels() const
Definition: deviceuiset.h:81
int m_masterTabIndex
Definition: mainwindow.h:310
void addSinkDevice()
Definition: mainwindow.cpp:347
const QString & getGroup() const
Definition: preset.h:72
void addSpectrumSink(BasebandSampleSink *spectrumSink)
Add a spectrum vis baseband sample sink.
int getDeviceSetIndex() const
Definition: mainwindow.h:118
DSPDeviceMIMOEngine * m_deviceMIMOEngine
Definition: deviceuiset.h:51
void setHardwareUserArguments(const QString &userArguments)
Definition: deviceapi.h:115
void saveCommandSettings()
Definition: mainwindow.cpp:795
virtual bool deserialize(const QByteArray &data)
MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser &parser, QWidget *parent=0)
Definition: mainwindow.cpp:95
void stop()
This thread stop.
void renameCommandGroup(const QString &oldGroupName, const QString &newGroupName)
QString findUserArgs(const QString &id, int sequence)
void on_action_Logging_triggered()
void setSourceIndex(int value)
Definition: mainsettings.h:49
void setSourceDeviceId(const QString &deviceId)
Definition: mainsettings.h:51
bool getRelease() const
Definition: command.h:58
QString group() const
bool isNewPreset() const
Definition: mainwindow.h:119
void deleteRxChannel(int channelIndex)