2017-10-24 18:29:18 +02:00
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QFont>
#include "gui/glspectrum.h"
#include "dsp/spectrumvis.h"
#include "gui/glspectrumgui.h"
#include "gui/channelwindow.h"
#include "gui/samplingdevicecontrol.h"
#include "dsp/dspdevicesourceengine.h"
#include "dsp/dspdevicesinkengine.h"
#include "device/devicesourceapi.h"
#include "device/devicesinkapi.h"
2017-10-30 22:45:53 +01:00
#include "plugin/plugininstancegui.h"
#include "plugin/pluginapi.h"
#include "plugin/plugininterface.h"
#include "settings/preset.h"
2017-10-24 18:29:18 +02:00
#include "deviceuiset.h"
2017-11-02 03:30:54 +01:00
DeviceUISet :: DeviceUISet ( int tabIndex , bool rxElseTx , QTimer & timer )
2017-10-24 18:29:18 +02:00
{
m_spectrum = new GLSpectrum ;
2018-01-22 14:07:24 +01:00
if ( rxElseTx ) {
m_spectrumVis = new SpectrumVis ( SDR_RX_SCALEF , m_spectrum );
} else {
m_spectrumVis = new SpectrumVis ( SDR_TX_SCALEF , m_spectrum );
}
2017-10-24 18:29:18 +02:00
m_spectrum -> connectTimer ( timer );
m_spectrumGUI = new GLSpectrumGUI ;
m_spectrumGUI -> setBuddies ( m_spectrumVis -> getInputMessageQueue (), m_spectrumVis , m_spectrum );
m_channelWindow = new ChannelWindow ;
2017-11-02 03:30:54 +01:00
m_samplingDeviceControl = new SamplingDeviceControl ( tabIndex , rxElseTx );
2017-10-24 18:29:18 +02:00
m_deviceSourceEngine = 0 ;
m_deviceSourceAPI = 0 ;
m_deviceSinkEngine = 0 ;
m_deviceSinkAPI = 0 ;
2017-11-01 20:06:33 +01:00
m_deviceTabIndex = tabIndex ;
2017-10-24 18:29:18 +02:00
// m_spectrum needs to have its font to be set since it cannot be inherited from the main window
QFont font ;
font . setFamily ( QStringLiteral ( "Sans Serif" ));
font . setPointSize ( 9 );
m_spectrum -> setFont ( font );
}
DeviceUISet ::~ DeviceUISet ()
{
delete m_samplingDeviceControl ;
delete m_channelWindow ;
delete m_spectrumGUI ;
delete m_spectrumVis ;
delete m_spectrum ;
}
2017-10-31 00:07:55 +01:00
void DeviceUISet :: addChannelMarker ( ChannelMarker * channelMarker )
{
m_spectrum -> addChannelMarker ( channelMarker );
}
void DeviceUISet :: addRollupWidget ( QWidget * widget )
{
m_channelWindow -> addRollupWidget ( widget );
}
2017-10-31 22:37:57 +01:00
void DeviceUISet :: registerRxChannelInstance ( const QString & channelName , PluginInstanceGUI * pluginGUI )
2017-10-30 22:45:53 +01:00
{
2017-10-31 22:37:57 +01:00
m_rxChannelInstanceRegistrations . append ( ChannelInstanceRegistration ( channelName , pluginGUI ));
renameRxChannelInstances ();
2017-10-30 22:45:53 +01:00
}
2017-10-31 22:37:57 +01:00
void DeviceUISet :: registerTxChannelInstance ( const QString & channelName , PluginInstanceGUI * pluginGUI )
2017-10-30 22:45:53 +01:00
{
2017-10-31 22:37:57 +01:00
m_txChannelInstanceRegistrations . append ( ChannelInstanceRegistration ( channelName , pluginGUI ));
2017-12-17 23:15:42 +01:00
renameTxChannelInstances ();
2017-10-31 22:37:57 +01:00
}
void DeviceUISet :: removeRxChannelInstance ( PluginInstanceGUI * pluginGUI )
{
for ( ChannelInstanceRegistrations :: iterator it = m_rxChannelInstanceRegistrations . begin (); it != m_rxChannelInstanceRegistrations . end (); ++ it )
{
if ( it -> m_gui == pluginGUI )
{
m_rxChannelInstanceRegistrations . erase ( it );
break ;
}
}
renameRxChannelInstances ();
}
void DeviceUISet :: removeTxChannelInstance ( PluginInstanceGUI * pluginGUI )
{
for ( ChannelInstanceRegistrations :: iterator it = m_txChannelInstanceRegistrations . begin (); it != m_txChannelInstanceRegistrations . end (); ++ it )
2017-10-30 22:45:53 +01:00
{
if ( it -> m_gui == pluginGUI )
{
2017-10-31 22:37:57 +01:00
m_txChannelInstanceRegistrations . erase ( it );
2017-10-30 22:45:53 +01:00
break ;
}
}
2017-12-17 23:15:42 +01:00
renameTxChannelInstances ();
2017-10-31 22:37:57 +01:00
}
void DeviceUISet :: freeRxChannels ()
{
for ( int i = 0 ; i < m_rxChannelInstanceRegistrations . count (); i ++ )
{
qDebug ( "DeviceUISet::freeAll: destroying channel [%s]" , qPrintable ( m_rxChannelInstanceRegistrations [ i ]. m_channelName ));
m_rxChannelInstanceRegistrations [ i ]. m_gui -> destroy ();
}
2017-10-30 22:45:53 +01:00
}
2017-10-31 22:37:57 +01:00
void DeviceUISet :: freeTxChannels ()
2017-10-30 22:45:53 +01:00
{
2017-10-31 22:37:57 +01:00
for ( int i = 0 ; i < m_txChannelInstanceRegistrations . count (); i ++ )
2017-10-30 22:45:53 +01:00
{
2017-10-31 22:37:57 +01:00
qDebug ( "DeviceUISet::freeAll: destroying channel [%s]" , qPrintable ( m_txChannelInstanceRegistrations [ i ]. m_channelName ));
m_txChannelInstanceRegistrations [ i ]. m_gui -> destroy ();
2017-10-30 22:45:53 +01:00
}
}
2017-12-23 23:41:37 +01:00
void DeviceUISet :: deleteRxChannel ( int channelIndex )
{
if (( channelIndex >= 0 ) && ( channelIndex < m_rxChannelInstanceRegistrations . count ()))
{
qDebug ( "DeviceUISet::deleteRxChennel: delete channel [%s] at %d" ,
qPrintable ( m_rxChannelInstanceRegistrations [ channelIndex ]. m_channelName ),
channelIndex );
m_rxChannelInstanceRegistrations [ channelIndex ]. m_gui -> destroy ();
m_rxChannelInstanceRegistrations . removeAt ( channelIndex );
renameRxChannelInstances ();
}
}
void DeviceUISet :: deleteTxChannel ( int channelIndex )
{
if (( channelIndex >= 0 ) && ( channelIndex < m_txChannelInstanceRegistrations . count ()))
{
qDebug ( "DeviceUISet::deleteTxChennel: delete channel [%s] at %d" ,
qPrintable ( m_txChannelInstanceRegistrations [ channelIndex ]. m_channelName ),
channelIndex );
m_txChannelInstanceRegistrations [ channelIndex ]. m_gui -> destroy ();
m_txChannelInstanceRegistrations . removeAt ( channelIndex );
renameTxChannelInstances ();
}
}
2017-10-31 22:37:57 +01:00
void DeviceUISet :: loadRxChannelSettings ( const Preset * preset , PluginAPI * pluginAPI )
2017-10-30 22:45:53 +01:00
{
if ( preset -> isSourcePreset ())
{
qDebug ( "DeviceUISet::loadChannelSettings: Loading preset [%s | %s]" , qPrintable ( preset -> getGroup ()), qPrintable ( preset -> getDescription ()));
// Available channel plugins
PluginAPI :: ChannelRegistrations * channelRegistrations = pluginAPI -> getRxChannelRegistrations ();
// copy currently open channels and clear list
2017-10-31 22:37:57 +01:00
ChannelInstanceRegistrations openChannels = m_rxChannelInstanceRegistrations ;
m_rxChannelInstanceRegistrations . clear ();
2017-10-30 22:45:53 +01:00
qDebug ( "DeviceUISet::loadChannelSettings: %d channel(s) in preset" , preset -> getChannelCount ());
for ( int i = 0 ; i < preset -> getChannelCount (); i ++ )
{
const Preset :: ChannelConfig & channelConfig = preset -> getChannelConfig ( i );
ChannelInstanceRegistration reg ;
// if we have one instance available already, use it
for ( int i = 0 ; i < openChannels . count (); i ++ )
{
2017-11-23 01:19:32 +01:00
qDebug ( "DeviceUISet::loadChannelSettings: channels compare [%s] vs [%s]" , qPrintable ( openChannels [ i ]. m_channelName ), qPrintable ( channelConfig . m_channelIdURI ));
2017-10-24 18:29:18 +02:00
2017-11-23 01:19:32 +01:00
if ( openChannels [ i ]. m_channelName == channelConfig . m_channelIdURI )
2017-10-30 22:45:53 +01:00
{
qDebug ( "DeviceSourceAPI::loadChannelSettings: channel [%s] found" , qPrintable ( openChannels [ i ]. m_channelName ));
reg = openChannels . takeAt ( i );
2017-10-31 22:37:57 +01:00
m_rxChannelInstanceRegistrations . append ( reg );
2017-10-30 22:45:53 +01:00
break ;
}
}
// if we haven't one already, create one
if ( reg . m_gui == NULL )
{
for ( int i = 0 ; i < channelRegistrations -> count (); i ++ )
{
2017-11-23 01:19:32 +01:00
if (( * channelRegistrations )[ i ]. m_channelIdURI == channelConfig . m_channelIdURI )
2017-10-30 22:45:53 +01:00
{
2017-11-23 01:19:32 +01:00
qDebug ( "DeviceUISet::loadChannelSettings: creating new channel [%s]" , qPrintable ( channelConfig . m_channelIdURI ));
2017-12-23 10:38:45 +01:00
BasebandSampleSink * rxChannel =
( * channelRegistrations )[ i ]. m_plugin -> createRxChannelBS ( m_deviceSourceAPI );
PluginInstanceGUI * rxChannelGUI =
( * channelRegistrations )[ i ]. m_plugin -> createRxChannelGUI ( this , rxChannel );
2017-12-23 10:32:02 +01:00
reg = ChannelInstanceRegistration ( channelConfig . m_channelIdURI , rxChannelGUI );
2017-10-30 22:45:53 +01:00
break ;
}
}
}
if ( reg . m_gui != NULL )
{
2017-11-23 01:19:32 +01:00
qDebug ( "DeviceUISet::loadChannelSettings: deserializing channel [%s]" , qPrintable ( channelConfig . m_channelIdURI ));
2017-10-30 22:45:53 +01:00
reg . m_gui -> deserialize ( channelConfig . m_config );
}
}
// everything, that is still "available" is not needed anymore
for ( int i = 0 ; i < openChannels . count (); i ++ )
{
qDebug ( "DeviceUISet::loadChannelSettings: destroying spare channel [%s]" , qPrintable ( openChannels [ i ]. m_channelName ));
openChannels [ i ]. m_gui -> destroy ();
}
2017-10-31 22:37:57 +01:00
renameRxChannelInstances ();
2017-10-30 22:45:53 +01:00
}
else
{
qDebug ( "DeviceUISet::loadChannelSettings: Loading preset [%s | %s] not a source preset" , qPrintable ( preset -> getGroup ()), qPrintable ( preset -> getDescription ()));
}
}
2017-10-31 22:37:57 +01:00
void DeviceUISet :: saveRxChannelSettings ( Preset * preset )
2017-10-30 22:45:53 +01:00
{
if ( preset -> isSourcePreset ())
{
2017-10-31 22:37:57 +01:00
qSort ( m_rxChannelInstanceRegistrations . begin (), m_rxChannelInstanceRegistrations . end ()); // sort by increasing delta frequency and type
2017-10-30 22:45:53 +01:00
2017-10-31 22:37:57 +01:00
for ( int i = 0 ; i < m_rxChannelInstanceRegistrations . count (); i ++ )
2017-10-30 22:45:53 +01:00
{
2017-10-31 22:37:57 +01:00
qDebug ( "DeviceUISet::saveChannelSettings: channel [%s] saved" , qPrintable ( m_rxChannelInstanceRegistrations [ i ]. m_channelName ));
preset -> addChannel ( m_rxChannelInstanceRegistrations [ i ]. m_channelName , m_rxChannelInstanceRegistrations [ i ]. m_gui -> serialize ());
2017-10-30 22:45:53 +01:00
}
}
else
{
2017-12-17 23:15:42 +01:00
qDebug ( "DeviceUISet::saveChannelSettings: not a source preset" );
2017-10-30 22:45:53 +01:00
}
}
2017-10-31 22:37:57 +01:00
void DeviceUISet :: loadTxChannelSettings ( const Preset * preset , PluginAPI * pluginAPI )
{
if ( preset -> isSourcePreset ())
{
qDebug ( "DeviceUISet::loadChannelSettings: Loading preset [%s | %s] not a sink preset" , qPrintable ( preset -> getGroup ()), qPrintable ( preset -> getDescription ()));
}
else
{
qDebug ( "DeviceUISet::loadChannelSettings: Loading preset [%s | %s]" , qPrintable ( preset -> getGroup ()), qPrintable ( preset -> getDescription ()));
// Available channel plugins
PluginAPI :: ChannelRegistrations * channelRegistrations = pluginAPI -> getTxChannelRegistrations ();
// copy currently open channels and clear list
ChannelInstanceRegistrations openChannels = m_txChannelInstanceRegistrations ;
m_txChannelInstanceRegistrations . clear ();
qDebug ( "DeviceUISet::loadChannelSettings: %d channel(s) in preset" , preset -> getChannelCount ());
for ( int i = 0 ; i < preset -> getChannelCount (); i ++ )
{
const Preset :: ChannelConfig & channelConfig = preset -> getChannelConfig ( i );
ChannelInstanceRegistration reg ;
// if we have one instance available already, use it
for ( int i = 0 ; i < openChannels . count (); i ++ )
{
2017-11-23 01:19:32 +01:00
qDebug ( "DeviceUISet::loadChannelSettings: channels compare [%s] vs [%s]" , qPrintable ( openChannels [ i ]. m_channelName ), qPrintable ( channelConfig . m_channelIdURI ));
2017-10-31 22:37:57 +01:00
2017-11-23 01:19:32 +01:00
if ( openChannels [ i ]. m_channelName == channelConfig . m_channelIdURI )
2017-10-31 22:37:57 +01:00
{
qDebug ( "DeviceUISet::loadChannelSettings: channel [%s] found" , qPrintable ( openChannels [ i ]. m_channelName ));
reg = openChannels . takeAt ( i );
m_txChannelInstanceRegistrations . append ( reg );
break ;
}
}
// if we haven't one already, create one
if ( reg . m_gui == 0 )
{
for ( int i = 0 ; i < channelRegistrations -> count (); i ++ )
{
2017-11-23 01:19:32 +01:00
if (( * channelRegistrations )[ i ]. m_channelIdURI == channelConfig . m_channelIdURI )
2017-10-31 22:37:57 +01:00
{
2017-11-23 01:19:32 +01:00
qDebug ( "DeviceUISet::loadChannelSettings: creating new channel [%s]" , qPrintable ( channelConfig . m_channelIdURI ));
2017-12-23 10:38:45 +01:00
BasebandSampleSource * txChannel =
( * channelRegistrations )[ i ]. m_plugin -> createTxChannelBS ( m_deviceSinkAPI );
PluginInstanceGUI * txChannelGUI =
( * channelRegistrations )[ i ]. m_plugin -> createTxChannelGUI ( this , txChannel );
2017-12-23 10:16:27 +01:00
reg = ChannelInstanceRegistration ( channelConfig . m_channelIdURI , txChannelGUI );
2017-10-31 22:37:57 +01:00
break ;
}
}
}
if ( reg . m_gui != 0 )
{
2017-11-23 01:19:32 +01:00
qDebug ( "DeviceUISet::loadChannelSettings: deserializing channel [%s]" , qPrintable ( channelConfig . m_channelIdURI ));
2017-10-31 22:37:57 +01:00
reg . m_gui -> deserialize ( channelConfig . m_config );
}
}
// everything, that is still "available" is not needed anymore
for ( int i = 0 ; i < openChannels . count (); i ++ )
{
qDebug ( "DeviceUISet::loadChannelSettings: destroying spare channel [%s]" , qPrintable ( openChannels [ i ]. m_channelName ));
openChannels [ i ]. m_gui -> destroy ();
}
renameTxChannelInstances ();
}
}
void DeviceUISet :: saveTxChannelSettings ( Preset * preset )
{
if ( preset -> isSourcePreset ())
{
qDebug ( "DeviceUISet::saveChannelSettings: not a sink preset" );
}
else
{
qSort ( m_txChannelInstanceRegistrations . begin (), m_txChannelInstanceRegistrations . end ()); // sort by increasing delta frequency and type
for ( int i = 0 ; i < m_txChannelInstanceRegistrations . count (); i ++ )
{
qDebug ( "DeviceUISet::saveChannelSettings: channel [%s] saved" , qPrintable ( m_txChannelInstanceRegistrations [ i ]. m_channelName ));
preset -> addChannel ( m_txChannelInstanceRegistrations [ i ]. m_channelName , m_txChannelInstanceRegistrations [ i ]. m_gui -> serialize ());
}
}
}
void DeviceUISet :: renameRxChannelInstances ()
{
for ( int i = 0 ; i < m_rxChannelInstanceRegistrations . count (); i ++ )
{
m_rxChannelInstanceRegistrations [ i ]. m_gui -> setName ( QString ( "%1:%2" ). arg ( m_rxChannelInstanceRegistrations [ i ]. m_channelName ). arg ( i ));
}
}
void DeviceUISet :: renameTxChannelInstances ()
2017-10-30 22:45:53 +01:00
{
2017-10-31 22:37:57 +01:00
for ( int i = 0 ; i < m_txChannelInstanceRegistrations . count (); i ++ )
2017-10-30 22:45:53 +01:00
{
2017-10-31 22:37:57 +01:00
m_txChannelInstanceRegistrations [ i ]. m_gui -> setName ( QString ( "%1:%2" ). arg ( m_txChannelInstanceRegistrations [ i ]. m_channelName ). arg ( i ));
2017-10-30 22:45:53 +01:00
}
}
// sort by increasing delta frequency and type (i.e. name)
bool DeviceUISet :: ChannelInstanceRegistration :: operator < ( const ChannelInstanceRegistration & other ) const
{
if ( m_gui && other . m_gui )
{
if ( m_gui -> getCenterFrequency () == other . m_gui -> getCenterFrequency ())
{
return m_gui -> getName () < other . m_gui -> getName ();
}
else
{
return m_gui -> getCenterFrequency () < other . m_gui -> getCenterFrequency ();
}
}
else
{
return false ;
}
}
2017-10-24 18:29:18 +02:00