diff --git a/src/source/tuner/TunerEditor.java b/src/source/tuner/TunerEditor.java index 6275174b..e1a2beb6 100644 --- a/src/source/tuner/TunerEditor.java +++ b/src/source/tuner/TunerEditor.java @@ -100,6 +100,7 @@ public class TunerEditor extends Editor listPanel.add( tableScroller, "span" ); mNewConfigurationButton.setEnabled( false ); + mNewConfigurationButton.setToolTipText( "Create a new configuration for the currently selected tuner" ); mNewConfigurationButton.addActionListener( new ActionListener() { @Override @@ -120,6 +121,7 @@ public class TunerEditor extends Editor listPanel.add( mNewConfigurationButton ); mDeleteConfigurationButton.setEnabled( false ); + mDeleteConfigurationButton.setToolTipText( "Deletes the currently selected tuner" ); mDeleteConfigurationButton.addActionListener( new ActionListener() { @Override @@ -140,6 +142,7 @@ public class TunerEditor extends Editor listPanel.add( mDeleteConfigurationButton ); mAssignConfigurationButton.setEnabled( false ); + mAssignConfigurationButton.setToolTipText( "Assigns to the currently selected tuner configuration to the selected tuner" ); mAssignConfigurationButton.addActionListener( new ActionListener() { @Override diff --git a/src/source/tuner/airspy/AirspyInformationPanel.java b/src/source/tuner/airspy/AirspyInformationPanel.java deleted file mode 100644 index 6b3ef2cb..00000000 --- a/src/source/tuner/airspy/AirspyInformationPanel.java +++ /dev/null @@ -1,77 +0,0 @@ -package source.tuner.airspy; - -/******************************************************************************* - * SDR Trunk - * Copyright (C) 2015 Dennis Sheirer - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - ******************************************************************************/ - -import javax.swing.JLabel; -import javax.swing.JPanel; - -import net.miginfocom.swing.MigLayout; - -public class AirspyInformationPanel extends JPanel -{ - private static final long serialVersionUID = 1L; - - private AirspyTunerController mController; - - /** - * Displays Airspy firmware, serial number and part identifier - */ - public AirspyInformationPanel( AirspyTunerController controller ) - { - mController = controller; - - initGUI(); - } - - private void initGUI() - { - setLayout( new MigLayout( "fill,wrap 2", - "[right,grow][grow]", - "[][][][][grow]" ) ); - - AirspyDeviceInformation info = mController.getDeviceInfo(); - - add( new JLabel( "Serial:" ) ); - add( new JLabel( info.getSerialNumber() ) ); - add( new JLabel( "Firmware:" ) ); - - //Split the firmware on spaces and use first value -- expose full - //string in a tool tip - String[] firmware = info.getVersion().split( " " ); - - JLabel firmwareLabel; - - if( firmware.length > 1 ) - { - firmwareLabel = new JLabel( firmware[ 0 ] ); - } - else - { - firmwareLabel = new JLabel( info.getVersion() ); - } - - firmwareLabel.setToolTipText( info.getVersion() ); - - add( firmwareLabel ); - add( new JLabel( "Part:" ) ); - add( new JLabel( info.getPartNumber() ) ); - add( new JLabel( "Board ID:" ) ); - add( new JLabel( info.getBoardID().getLabel() ) ); - } -} diff --git a/src/source/tuner/airspy/AirspyTunerConfigurationPanel.java b/src/source/tuner/airspy/AirspyTunerConfigurationPanel.java deleted file mode 100644 index 60617e57..00000000 --- a/src/source/tuner/airspy/AirspyTunerConfigurationPanel.java +++ /dev/null @@ -1,695 +0,0 @@ -/******************************************************************************* - * SDR Trunk - * Copyright (C) 2014 Dennis Sheirer - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - ******************************************************************************/ -package source.tuner.airspy; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.util.List; - -import javax.swing.ComboBoxModel; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JSeparator; -import javax.swing.JSlider; -import javax.swing.JTextField; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.usb.UsbException; - -import net.miginfocom.swing.MigLayout; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.usb4java.LibUsbException; - -import settings.SettingsManager; -import source.SourceException; -import source.tuner.airspy.AirspyTunerController.Gain; -import source.tuner.airspy.AirspyTunerController.GainMode; - -public class AirspyTunerConfigurationPanel extends JPanel -{ - private final static Logger mLog = - LoggerFactory.getLogger( AirspyTunerConfigurationPanel.class ); - - private static final long serialVersionUID = 1L; - - private SettingsManager mSettingsManager; - private AirspyTunerController mController; - private AirspyTunerConfiguration mSelectedConfig; - - private JButton mNewConfiguration; - private JButton mDeleteConfiguration; - private JComboBox mComboConfigurations; - - private JTextField mName; - - private JComboBox mSampleRateCombo; - - private JComboBox mGainModeCombo; - private JLabel mGainLabel; - private JLabel mGainFillerLabel; - private JLabel mGainValueLabel; - private JSlider mGain; - - private JLabel mIFGainLabel; - private JLabel mIFGainFillerLabel; - private JLabel mIFGainValueLabel; - private JSlider mIFGain; - - private JLabel mLNAGainLabel; - private JCheckBox mLNAAGC; - private JLabel mLNAGainValueLabel; - private JSlider mLNAGain; - - private JLabel mMixerGainValueLabel; - private JCheckBox mMixerAGC; - private JLabel mMixerGainLabel; - private JSlider mMixerGain; - - - public AirspyTunerConfigurationPanel( SettingsManager settingsManager, - AirspyTunerController controller ) - { - mSettingsManager = settingsManager; - mController = controller; - - init(); - } - - /** - * Initializes the gui components - */ - private void init() - { - setLayout( new MigLayout( "fill,wrap 4", "[left][grow][grow][right]", - "[][][][][][][grow]" ) ); - - /** - * Tuner configuration selector - */ - mComboConfigurations = new JComboBox(); - - mComboConfigurations.setModel( getModel() ); - - /* Determine which tuner configuration should be selected/displayed */ -// TunerConfigurationAssignment savedConfig = null; - String serial = null; - - serial = mController.getDeviceInfo().getSerialNumber(); - - if( serial != null ) - { -// savedConfig = mSettingsManager.getSelectedTunerConfiguration( -// TunerType.AIRSPY_R820T, serial ); - } - -// if( savedConfig != null ) -// { -// mSelectedConfig = getNamedConfiguration( -// savedConfig.getTunerConfigurationName() ); -// } - - /* If we couldn't determine the saved/selected config, use the first one */ - if( mSelectedConfig == null ) - { - mSelectedConfig = mComboConfigurations.getItemAt( 0 ); - - //Store this config as the default for this tuner at this address - - if( serial != null ) - { -// mSettingsManager.setSelectedTunerConfiguration( TunerType.AIRSPY_R820T, -// serial, mSelectedConfig ); - } - } - - mComboConfigurations.setSelectedItem( mSelectedConfig ); - - mComboConfigurations.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( ActionEvent e ) - { - AirspyTunerConfiguration selected = - (AirspyTunerConfiguration)mComboConfigurations - .getItemAt( mComboConfigurations.getSelectedIndex() ); - - if( selected != null ) - { - update( selected ); - } - } - }); - - add( new JLabel( "Config:" ) ); - add( mComboConfigurations, "span,growx,push" ); - - add( new JSeparator(), "span,growx,push" ); - - - /** - * Tuner Configuration Name - */ - mName = new JTextField(); - mName.setText( mSelectedConfig.getName() ); - - mName.addFocusListener( new FocusListener() - { - @Override - public void focusLost( FocusEvent e ) - { - mSelectedConfig.setName( mName.getText() ); - save(); - } - @Override - public void focusGained( FocusEvent e ) {} - } ); - - add( new JLabel( "Name:" ) ); - add( mName, "span,growx,push" ); - - /** - * Sample Rate - */ - add( new JLabel( "Sample Rate:" ) ); - - List rates = mController.getSampleRates(); - - mSampleRateCombo = new JComboBox( - new DefaultComboBoxModel( rates.toArray( - new AirspySampleRate[ rates.size() ] ) ) ); - - mSampleRateCombo.setSelectedItem( mController.getSampleRate() ); - - mSampleRateCombo.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( ActionEvent e ) - { - AirspySampleRate rate = (AirspySampleRate)mSampleRateCombo.getSelectedItem(); - - try - { - mController.setSampleRate( rate ); - mSelectedConfig.setSampleRate( rate.getRate() ); - save(); - } - catch ( LibUsbException | UsbException e1 ) - { - JOptionPane.showMessageDialog( AirspyTunerConfigurationPanel.this, - "Couldn't set sample rate to " + rate.getLabel() ); - - mLog.error( "Error setting airspy sample rate", e1 ); - } - } - } ); - - add( mSampleRateCombo, "span 3,growx" ); - - add( new JSeparator(), "span,growx,push" ); - - /** - * Gain Mode - */ - add( new JLabel( "Gain Mode:" ) ); - mGainModeCombo = new JComboBox( GainMode.values() ); - mGainModeCombo.setSelectedItem( Gain.getGainMode( mSelectedConfig.getGain() ) ); - mGainModeCombo.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( ActionEvent e ) - { - GainMode mode = (GainMode)mGainModeCombo.getSelectedItem(); - updateGainComponents( mode ); - - switch( mode ) - { - case LINEARITY: - mGain.setValue( AirspyTunerController.LINEARITY_GAIN_DEFAULT.getValue() ); - mSelectedConfig.setGain( AirspyTunerController.LINEARITY_GAIN_DEFAULT ); - break; - case SENSITIVITY: - mGain.setValue( AirspyTunerController.SENSITIVITY_GAIN_DEFAULT.getValue() ); - mSelectedConfig.setGain( AirspyTunerController.SENSITIVITY_GAIN_DEFAULT ); - break; - case CUSTOM: - default: - mLNAGain.setValue( mSelectedConfig.getLNAGain() ); - mMixerGain.setValue( mSelectedConfig.getMixerGain() ); - mIFGain.setValue( mSelectedConfig.getIFGain() ); - mSelectedConfig.setGain( Gain.CUSTOM ); - break; - } - - save(); - } - } ); - - add( mGainModeCombo, "wrap" ); - - /** - * Gain - */ - mGainLabel = new JLabel( "Gain" ); - add( mGainLabel ); - mGainFillerLabel = new JLabel( "" ); - add( mGainFillerLabel, "span 2" ); - mGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getGain().getValue() ) ); - add( mGainValueLabel, "wrap" ); - mGain = new JSlider( JSlider.HORIZONTAL, - AirspyTunerController.GAIN_MIN, - AirspyTunerController.GAIN_MAX, - mSelectedConfig.getGain().getValue() ); - mGain.setMajorTickSpacing( 1 ); - mGain.setPaintTicks( true ); - - mGain.addChangeListener( new ChangeListener() - { - @Override - public void stateChanged( ChangeEvent event ) - { - GainMode mode = (GainMode)mGainModeCombo.getSelectedItem(); - int value = mGain.getValue(); - Gain gain = Gain.getGain( mode, value ); - - try - { - mController.setGain( gain ); - mSelectedConfig.setGain( gain ); - save(); - mGainValueLabel.setText( String.valueOf( gain.getValue() ) ); - } - catch ( Exception e ) - { - mLog.error( "Couldn't set airspy gain to:" + gain.name(), e ); - - JOptionPane.showMessageDialog( mGain, - "Couldn't set gain value to " + gain.getValue() ); - - mGain.setValue( mSelectedConfig.getGain().getValue() ); - } - } - } ); - - add( mGain, "span,grow" ); - - /** - * IF/VGA Gain - */ - mIFGainLabel = new JLabel( "IF Gain" ); - add( mIFGainLabel ); - mIFGainFillerLabel = new JLabel( "" ); - add( mIFGainFillerLabel, "span 2" ); - mIFGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getIFGain() ) ); - add( mIFGainValueLabel, "wrap" ); - - mIFGain = new JSlider( JSlider.HORIZONTAL, - AirspyTunerController.IF_GAIN_MIN, - AirspyTunerController.IF_GAIN_MAX, - mSelectedConfig.getIFGain() ); - - mIFGain.setMajorTickSpacing( 1 ); - mIFGain.setPaintTicks( true ); - - mIFGain.addChangeListener( new ChangeListener() - { - @Override - public void stateChanged( ChangeEvent event ) - { - int gain = mIFGain.getValue(); - - try - { - mController.setIFGain( gain ); - mSelectedConfig.setIFGain( gain ); - save(); - mIFGainValueLabel.setText( String.valueOf( gain ) ); - } - catch ( Exception e ) - { - mLog.error( "Couldn't set airspy IF gain to:" + gain, e ); - - JOptionPane.showMessageDialog( mIFGain, - "Couldn't set IF gain value to " + gain ); - - mIFGain.setValue( mSelectedConfig.getIFGain() ); - } - } - } ); - - add( mIFGain, "span,grow" ); - - /** - * Mixer Gain - */ - mMixerGainLabel = new JLabel( "Mixer Gain" ); - add( mMixerGainLabel ); - - mMixerAGC = new JCheckBox( "AGC" ); - mMixerAGC.setSelected( mSelectedConfig.isMixerAGC() ); - mMixerAGC.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( ActionEvent e ) - { - try - { - mController.setMixerAGC( !mSelectedConfig.isMixerAGC() ); - mSelectedConfig.setMixerAGC( !mSelectedConfig.isMixerAGC() ); - save(); - } - catch ( Exception e1 ) - { - mLog.error( "Error setting Mixer AGC Enabled:" + !mSelectedConfig.isMixerAGC() ); - mMixerAGC.setSelected( mSelectedConfig.isMixerAGC() ); - } - } - } ); - - - add( mMixerAGC, "span 2,center" ); - - mMixerGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getMixerGain() ) ); - add( mMixerGainValueLabel, "wrap" ); - - mMixerGain = new JSlider( JSlider.HORIZONTAL, - AirspyTunerController.MIXER_GAIN_MIN, - AirspyTunerController.MIXER_GAIN_MAX, - mSelectedConfig.getMixerGain() ); - - mMixerGain.setMajorTickSpacing( 1 ); - mMixerGain.setPaintTicks( true ); - - mMixerGain.addChangeListener( new ChangeListener() - { - @Override - public void stateChanged( ChangeEvent event ) - { - int gain = mMixerGain.getValue(); - - try - { - mController.setMixerGain( gain ); - mSelectedConfig.setMixerGain( gain ); - save(); - mMixerGainValueLabel.setText( String.valueOf( gain ) ); - } - catch ( Exception e ) - { - mLog.error( "Couldn't set airspy Mixer gain to:" + gain, e ); - - JOptionPane.showMessageDialog( mIFGain, "Couldn't set Mixer gain value to " + gain ); - - mMixerGain.setValue( mSelectedConfig.getMixerGain() ); - } - } - } ); - - add( mMixerGain, "span,grow" ); - - /** - * LNA Gain - */ - mLNAGainLabel = new JLabel( "LNA Gain" ); - add( mLNAGainLabel ); - - mLNAAGC = new JCheckBox( "AGC" ); - mLNAAGC.setSelected( mSelectedConfig.isLNAAGC() ); - mLNAAGC.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( ActionEvent e ) - { - try - { - mController.setLNAAGC( !mSelectedConfig.isLNAAGC() ); - mSelectedConfig.setLNAAGC( !mSelectedConfig.isLNAAGC() ); - save(); - } - catch ( Exception e1 ) - { - mLog.error( "Error setting LNA AGC Enabled:" + !mSelectedConfig.isLNAAGC() ); - mLNAAGC.setSelected( mSelectedConfig.isLNAAGC() ); - } - - } - } ); - - add( mLNAAGC, "span 2,center" ); - - mLNAGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getLNAGain() ) ); - add( mLNAGainValueLabel, "wrap" ); - - mLNAGain = new JSlider( JSlider.HORIZONTAL, - AirspyTunerController.LNA_GAIN_MIN, - AirspyTunerController.LNA_GAIN_MAX, - mSelectedConfig.getLNAGain() ); - - mLNAGain.setMajorTickSpacing( 1 ); - mLNAGain.setPaintTicks( true ); - - mLNAGain.addChangeListener( new ChangeListener() - { - @Override - public void stateChanged( ChangeEvent event ) - { - int gain = mLNAGain.getValue(); - - try - { - mController.setLNAGain( gain ); - mSelectedConfig.setLNAGain( gain ); - save(); - mLNAGainValueLabel.setText( String.valueOf( gain ) ); - } - catch ( Exception e ) - { - mLog.error( "Couldn't set airspy LNA gain to:" + gain, e ); - - JOptionPane.showMessageDialog( mIFGain, "Couldn't set LNA gain value to " + gain ); - - mLNAGain.setValue( mSelectedConfig.getLNAGain() ); - } - } - } ); - - add( mLNAGain, "span,grow" ); - - //Set the enabled state of each of the gain controls - updateGainComponents( (GainMode)mGainModeCombo.getSelectedItem() ); - - /** - * Create a new configuration - */ - mNewConfiguration = new JButton( "New" ); - - mNewConfiguration.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( ActionEvent e ) - { -// TunerConfiguration config = -// mSettingsManager.addNewTunerConfiguration( -// TunerType.AIRSPY_R820T, -// "New Configuration" ); -// -// mComboConfigurations.setModel( getModel() ); -// -// mComboConfigurations.setSelectedItem( config ); -// -// repaint(); - } - } ); - - add( mNewConfiguration, "span 2,growx,push" ); - - /** - * Delete the currently selected configuration - */ - mDeleteConfiguration = new JButton( "Delete" ); - - mDeleteConfiguration.addActionListener( new ActionListener() - { - @Override - public void actionPerformed( ActionEvent e ) - { - AirspyTunerConfiguration selected = - (AirspyTunerConfiguration)mComboConfigurations - .getItemAt( mComboConfigurations.getSelectedIndex() ); - - if( selected != null ) - { - int n = JOptionPane.showConfirmDialog( - AirspyTunerConfigurationPanel.this, - "Are you sure you want to delete '" - + selected.getName() + "'?", - "Are you sure?", - JOptionPane.YES_NO_OPTION ); - - if( n == JOptionPane.YES_OPTION ) - { -// mSettingsManager.deleteTunerConfiguration( selected ); - - mComboConfigurations.setModel( getModel() ); - - mComboConfigurations.setSelectedIndex( 0 ); - - repaint(); - } - } - } - } ); - - add( mDeleteConfiguration, "span 2,growx,push" ); - } - - /** - * Updates the enabled state of each of the gain controls according to the - * specified gain mode. The overall gain controls are enabled for linearity - * and sensitivity and the individual gain controls are disabled, and - * vice-versa for custom mode. - */ - private void updateGainComponents( GainMode mode ) - { - boolean isCustom = ( mode == GainMode.CUSTOM ); - - mGainLabel.setEnabled( !isCustom ); - mGainFillerLabel.setEnabled( !isCustom ); - mGainValueLabel.setEnabled( !isCustom ); - mGain.setEnabled( !isCustom ); - mIFGainLabel.setEnabled( isCustom ); - mIFGainFillerLabel.setEnabled( isCustom ); - mIFGainValueLabel.setEnabled( isCustom ); - mIFGain.setEnabled( isCustom ); - mLNAGainLabel.setEnabled( isCustom ); - mLNAAGC.setEnabled( isCustom ); - mLNAGainValueLabel.setEnabled( isCustom ); - mLNAGain.setEnabled( isCustom ); - mMixerGainValueLabel.setEnabled( isCustom ); - mMixerAGC.setEnabled( isCustom ); - mMixerGainLabel.setEnabled( isCustom ); - mMixerGain.setEnabled( isCustom ); - } - - /** - * Updates gui controls with the values from the tuner configuration - * @param config - tuner configuration - */ - private void update( AirspyTunerConfiguration config ) - { - mSelectedConfig = config; - - try - { - mController.apply( config ); - - mName.setText( config.getName() ); - - AirspySampleRate rate = mController.getSampleRate( - mSelectedConfig.getSampleRate() ); - - if( rate != null ) - { - mSampleRateCombo.setSelectedItem( rate ); - } - - mIFGain.setValue( mSelectedConfig.getIFGain() ); - mMixerGain.setValue( mSelectedConfig.getMixerGain() ); - mLNAGain.setValue( mSelectedConfig.getLNAGain() ); - - mMixerAGC.setSelected( mSelectedConfig.isMixerAGC() ); - mLNAAGC.setSelected( mSelectedConfig.isLNAAGC() ); - - Gain gain = mSelectedConfig.getGain(); - mGainModeCombo.setSelectedItem( Gain.getGainMode( gain ) ); - mGain.setValue( gain.getValue() ); - -// mSettingsManager.setSelectedTunerConfiguration( -// TunerType.AIRSPY_R820T, mController.getDeviceInfo().getSerialNumber(), config ); - - save(); - } - catch ( /*UsbException |*/ SourceException e1 ) - { - JOptionPane.showMessageDialog( - AirspyTunerConfigurationPanel.this, - "Airspy Tuner Controller - couldn't " - + "apply the tuner configuration settings - " + - e1.getLocalizedMessage() ); - - mLog.error( "Airspy Tuner Controller - couldn't apply " - + "config [" + config.getName() + "]", e1 ); - } - } - - /** - * Constructs a combo box model for the tuner configuration combo component - * by assembling a list of the tuner configurations appropriate for this - * specific tuner - */ - private ComboBoxModel getModel() - { -// ArrayList configs = -// mSettingsManager.getTunerConfigurations( TunerType.AIRSPY_R820T ); - - DefaultComboBoxModel model = - new DefaultComboBoxModel(); - -// for( TunerConfiguration config: configs ) -// { -// model.addElement( (AirspyTunerConfiguration)config ); -// } - - return model; - } - - /** - * Retrieves a specific (named) tuner configuration - */ - private AirspyTunerConfiguration getNamedConfiguration( String name ) - { -// ArrayList configs = -// mSettingsManager.getTunerConfigurations( TunerType.AIRSPY_R820T ); - -// for( TunerConfiguration config: configs ) -// { -// if( config.getName().contentEquals( name ) ) -// { -// return (AirspyTunerConfiguration)config; -// } -// } - - return null; - } - - /** - * Saves current tuner configuration settings - */ - private void save() - { -// mSettingsManager.save(); - } -} diff --git a/src/source/tuner/airspy/AirspyTunerEditor.java b/src/source/tuner/airspy/AirspyTunerEditor.java new file mode 100644 index 00000000..36066eaa --- /dev/null +++ b/src/source/tuner/airspy/AirspyTunerEditor.java @@ -0,0 +1,720 @@ +/******************************************************************************* + * SDR Trunk + * Copyright (C) 2015-2016 Dennis Sheirer + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + ******************************************************************************/ +package source.tuner.airspy; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.text.DecimalFormat; +import java.util.List; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JSeparator; +import javax.swing.JSlider; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.SpinnerModel; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.usb.UsbException; + +import net.miginfocom.swing.MigLayout; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.usb4java.LibUsbException; + +import source.SourceException; +import source.tuner.airspy.AirspyTunerController.Gain; +import source.tuner.airspy.AirspyTunerController.GainMode; +import source.tuner.configuration.TunerConfiguration; +import source.tuner.configuration.TunerConfigurationEditor; +import source.tuner.configuration.TunerConfigurationModel; + +public class AirspyTunerEditor extends TunerConfigurationEditor +{ + private static final long serialVersionUID = 1L; + + private final static Logger mLog = + LoggerFactory.getLogger( AirspyTunerEditor.class ); + + private JTextField mConfigurationName; + private JButton mTunerInfo; + + private JComboBox mSampleRateCombo; + private JSpinner mFrequencyCorrection; + + private JComboBox mGainModeCombo; + + private JSlider mMasterGain; + private JLabel mMasterGainValueLabel; + + private JSlider mIFGain; + private JLabel mIFGainValueLabel; + + private JSlider mLNAGain; + private JLabel mLNAGainValueLabel; + + private JSlider mMixerGain; + private JLabel mMixerGainValueLabel; + + private JCheckBox mLNAAGC; + private JCheckBox mMixerAGC; + + private AirspyTunerController mController; + private boolean mLoading; + + public AirspyTunerEditor( TunerConfigurationModel tunerConfigurationModel, + AirspyTuner tuner ) + { + super( tunerConfigurationModel ); + mController = tuner.getController(); + + init(); + } + + private AirspyTunerConfiguration getConfiguration() + { + if( hasItem() ) + { + return (AirspyTunerConfiguration)getItem(); + } + + return null; + } + + private void init() + { + setLayout( new MigLayout( "fill,wrap 4", "[right][grow,fill][right][grow,fill]", + "[][][][][][grow]" ) ); + + add( new JLabel( "Airspy Tuner Configuration" ), "span,align center" ); + +// tabs.add( "Info", new AirspyInformationPanel( mController ) ); + + mConfigurationName = new JTextField(); + mConfigurationName.setEnabled( false ); + mConfigurationName.addFocusListener( new FocusListener() + { + @Override + public void focusLost( FocusEvent e ) + { + save(); + } + @Override + public void focusGained( FocusEvent e ) {} + } ); + + add( new JLabel( "Name:" ) ); + add( mConfigurationName, "span 2" ); + + mTunerInfo = new JButton( "Tuner Info" ); + mTunerInfo.setEnabled( false ); + mTunerInfo.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + JOptionPane.showMessageDialog( AirspyTunerEditor.this, getTunerInfo(), + "Tuner Info", JOptionPane.INFORMATION_MESSAGE ); + } + } ); + add( mTunerInfo ); + + /** + * Sample Rate + */ + add( new JLabel( "Sample Rate:" ) ); + + List rates = mController.getSampleRates(); + + mSampleRateCombo = new JComboBox( + new DefaultComboBoxModel( rates.toArray( + new AirspySampleRate[ rates.size() ] ) ) ); + mSampleRateCombo.setEnabled( false ); + mSampleRateCombo.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + AirspySampleRate rate = (AirspySampleRate)mSampleRateCombo.getSelectedItem(); + + try + { + mController.setSampleRate( rate ); + save(); + } + catch ( LibUsbException | UsbException e1 ) + { + JOptionPane.showMessageDialog( AirspyTunerEditor.this, + "Couldn't set sample rate to " + rate.getLabel() ); + + mLog.error( "Error setting airspy sample rate", e1 ); + } + } + } ); + + add( mSampleRateCombo ); + + /** + * Frequency Correction + */ + SpinnerModel model = + new SpinnerNumberModel( 0.0, //initial value + -1000.0, //min + 1000.0, //max + 0.1 ); //step + + mFrequencyCorrection = new JSpinner( model ); + mFrequencyCorrection.setEnabled( false ); + + JSpinner.NumberEditor editor = + (JSpinner.NumberEditor)mFrequencyCorrection.getEditor(); + + DecimalFormat format = editor.getFormat(); + format.setMinimumFractionDigits( 1 ); + editor.getTextField().setHorizontalAlignment( SwingConstants.CENTER ); + + mFrequencyCorrection.addChangeListener( new ChangeListener() + { + @Override + public void stateChanged( ChangeEvent e ) + { + final double value = ((SpinnerNumberModel)mFrequencyCorrection + .getModel()).getNumber().doubleValue(); + + try + { + mController.setFrequencyCorrection( value ); + } + catch ( SourceException e1 ) + { + mLog.error( "Error setting frequency correction value", e1 ); + } + + save(); + } + } ); + + add( new JLabel( "PPM:" ) ); + add( mFrequencyCorrection ); + + add( new JSeparator(), "span,growx,push" ); + + /** + * Gain Mode + */ + add( new JLabel( "Gain Mode:" ) ); + mGainModeCombo = new JComboBox( GainMode.values() ); + mGainModeCombo.setEnabled( false ); + mGainModeCombo.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + GainMode mode = (GainMode)mGainModeCombo.getSelectedItem(); + + updateGainComponents( mode ); + + if( hasItem() ) + { + AirspyTunerConfiguration airspy = getConfiguration(); + + Gain gain = airspy.getGain(); + + if( mode == GainMode.CUSTOM ) + { + mIFGain.setValue( airspy.getIFGain() ); + mMixerGain.setValue( airspy.getMixerGain() ); + mMixerAGC.setSelected( airspy.isMixerAGC() ); + mLNAGain.setValue( airspy.getLNAGain() ); + mLNAAGC.setSelected( airspy.isLNAAGC() ); + } + else + { + mMixerAGC.setSelected( false ); + mLNAAGC.setSelected( false ); + mMasterGain.setValue( gain.getValue() ); + mIFGain.setValue( gain.getIF() ); + mMixerGain.setValue( gain.getMixer() ); + mLNAGain.setValue( gain.getLNA() ); + } + } + + save(); + } + } ); + + add( mGainModeCombo, "wrap" ); + + /** + * Gain + */ + add( new JLabel( "Master:" ) ); + + mMasterGain = new JSlider( JSlider.HORIZONTAL, + AirspyTunerController.GAIN_MIN, + AirspyTunerController.GAIN_MAX, + AirspyTunerController.GAIN_MIN ); + mMasterGain.setMajorTickSpacing( 1 ); + mMasterGain.setPaintTicks( true ); + + mMasterGain.addChangeListener( new ChangeListener() + { + @Override + public void stateChanged( ChangeEvent event ) + { + GainMode mode = (GainMode)mGainModeCombo.getSelectedItem(); + int value = mMasterGain.getValue(); + Gain gain = Gain.getGain( mode, value ); + + try + { + mController.setGain( gain ); + save(); + mMasterGainValueLabel.setText( String.valueOf( gain.getValue() ) ); + } + catch ( Exception e ) + { + mLog.error( "Couldn't set airspy gain to:" + gain.name(), e ); + JOptionPane.showMessageDialog( mMasterGain, "Couldn't set gain value to " + + gain.getValue() ); + } + } + } ); + + add( mMasterGain, "span 2" ); + + mMasterGainValueLabel = new JLabel( "0" ); + add( mMasterGainValueLabel ); + + add( new JLabel( "IF:" ) ); + + mIFGain = new JSlider( JSlider.HORIZONTAL, + AirspyTunerController.IF_GAIN_MIN, + AirspyTunerController.IF_GAIN_MAX, + AirspyTunerController.IF_GAIN_MIN ); + + mIFGain.setMajorTickSpacing( 1 ); + mIFGain.setPaintTicks( true ); + + mIFGain.addChangeListener( new ChangeListener() + { + @Override + public void stateChanged( ChangeEvent event ) + { + int gain = mIFGain.getValue(); + + try + { + mController.setIFGain( gain ); + save(); + mIFGainValueLabel.setText( String.valueOf( gain ) ); + } + catch ( Exception e ) + { + mLog.error( "Couldn't set airspy IF gain to:" + gain, e ); + + JOptionPane.showMessageDialog( mIFGain, "Couldn't set IF gain value to " + gain ); + } + } + } ); + + add( mIFGain, "span 2" ); + + mIFGainValueLabel = new JLabel( "0" ); + add( mIFGainValueLabel ); + + /** + * Mixer Gain + */ + add( new JLabel( "Mixer:" ) ); + + mMixerGain = new JSlider( JSlider.HORIZONTAL, + AirspyTunerController.MIXER_GAIN_MIN, + AirspyTunerController.MIXER_GAIN_MAX, + AirspyTunerController.MIXER_GAIN_MIN ); + + mMixerGain.setMajorTickSpacing( 1 ); + mMixerGain.setPaintTicks( true ); + + mMixerGain.addChangeListener( new ChangeListener() + { + @Override + public void stateChanged( ChangeEvent event ) + { + int gain = mMixerGain.getValue(); + + try + { + mController.setMixerGain( gain ); + save(); + mMixerGainValueLabel.setText( String.valueOf( gain ) ); + } + catch ( Exception e ) + { + mLog.error( "Couldn't set airspy Mixer gain to:" + gain, e ); + JOptionPane.showMessageDialog( mIFGain, "Couldn't set Mixer gain value to " + gain ); + } + } + } ); + + add( mMixerGain, "span 2" ); + + mMixerGainValueLabel = new JLabel( "0" ); + add( mMixerGainValueLabel ); + + add( new JLabel( "LNA:" ) ); + + mLNAGain = new JSlider( JSlider.HORIZONTAL, + AirspyTunerController.LNA_GAIN_MIN, + AirspyTunerController.LNA_GAIN_MAX, + AirspyTunerController.LNA_GAIN_MIN ); + + mLNAGain.setMajorTickSpacing( 1 ); + mLNAGain.setPaintTicks( true ); + + mLNAGain.addChangeListener( new ChangeListener() + { + @Override + public void stateChanged( ChangeEvent event ) + { + int gain = mLNAGain.getValue(); + + try + { + mController.setLNAGain( gain ); + save(); + mLNAGainValueLabel.setText( String.valueOf( gain ) ); + } + catch ( Exception e ) + { + mLog.error( "Couldn't set airspy LNA gain to:" + gain, e ); + JOptionPane.showMessageDialog( mIFGain, "Couldn't set LNA gain value to " + gain ); + } + } + } ); + + add( mLNAGain, "span 2" ); + + mLNAGainValueLabel = new JLabel( "0" ); + add( mLNAGainValueLabel ); + + mMixerAGC = new JCheckBox( "Mixer AGC" ); + mMixerAGC.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + try + { + mController.setMixerAGC( mMixerAGC.isSelected() ); + save(); + } + catch ( Exception e1 ) + { + mLog.error( "Error setting Mixer AGC Enabled" ); + } + } + } ); + + add( mMixerAGC, "span 2,center" ); + + mLNAAGC = new JCheckBox( "LNA AGC" ); + mLNAAGC.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + try + { + mController.setLNAAGC( mLNAAGC.isSelected() ); + save(); + } + catch ( Exception e1 ) + { + mLog.error( "Error setting LNA AGC Enabled" ); + } + + } + } ); + + add( mLNAAGC, "span 2,center" ); + } + + /** + * Updates the enabled state of each of the gain controls according to the + * specified gain mode. The master gain control is enabled for linearity + * and sensitivity and the individual gain controls are disabled, and + * vice-versa for custom mode. + */ + private void updateGainComponents( GainMode mode ) + { + switch( mode ) + { + case LINEARITY: + if( !mMasterGain.isEnabled() ) + { + mMasterGain.setEnabled( true ); + mMasterGainValueLabel.setEnabled( true ); + } + if( mIFGain.isEnabled() ) + { + mIFGain.setEnabled( false ); + mIFGainValueLabel.setEnabled( false ); + } + if( mLNAGain.isEnabled() ) + { + mLNAAGC.setEnabled( false ); + mLNAGainValueLabel.setEnabled( false ); + mLNAGain.setEnabled( false ); + } + if( mMixerGain.isEnabled() ) + { + mMixerGainValueLabel.setEnabled( false ); + mMixerAGC.setEnabled( false ); + mMixerGain.setEnabled( false ); + } + break; + case SENSITIVITY: + if( !mMasterGain.isEnabled() ) + { + mMasterGain.setEnabled( true ); + mMasterGainValueLabel.setEnabled( true ); + } + if( mIFGain.isEnabled() ) + { + mIFGain.setEnabled( false ); + mIFGainValueLabel.setEnabled( false ); + } + if( mLNAGain.isEnabled() ) + { + mLNAAGC.setEnabled( false ); + mLNAGainValueLabel.setEnabled( false ); + mLNAGain.setEnabled( false ); + } + if( mMixerGain.isEnabled() ) + { + mMixerGainValueLabel.setEnabled( false ); + mMixerAGC.setEnabled( false ); + mMixerGain.setEnabled( false ); + } + break; + case CUSTOM: + if( mMasterGain.isEnabled() ) + { + mMasterGain.setEnabled( false ); + mMasterGainValueLabel.setEnabled( false ); + } + if( !mIFGain.isEnabled() ) + { + mIFGain.setEnabled( true ); + mIFGainValueLabel.setEnabled( true ); + } + if( !mLNAGain.isEnabled() ) + { + mLNAAGC.setEnabled( true ); + mLNAGainValueLabel.setEnabled( true ); + mLNAGain.setEnabled( true ); + } + if( !mMixerGain.isEnabled() ) + { + mMixerGainValueLabel.setEnabled( true ); + mMixerAGC.setEnabled( true ); + mMixerGain.setEnabled( true ); + } + default: + break; + } + } + + @Override + public void save() + { + if( hasItem() && !mLoading ) + { + AirspyTunerConfiguration config = getConfiguration(); + config.setName( mConfigurationName.getText() ); + config.setSampleRate( ((AirspySampleRate)mSampleRateCombo.getSelectedItem()).getRate() ); + + double value = ((SpinnerNumberModel)mFrequencyCorrection.getModel()).getNumber().doubleValue(); + config.setFrequencyCorrection( value ); + + config.setGain( Gain.getGain( (GainMode)mGainModeCombo.getSelectedItem(), mMasterGain.getValue() ) ); + config.setIFGain( mIFGain.getValue() ); + config.setMixerGain( mMixerGain.getValue() ); + config.setLNAGain( mLNAGain.getValue() ); + config.setMixerAGC( mMixerAGC.isSelected() ); + config.setLNAAGC( mLNAAGC.isSelected() ); + } + } + + private AirspySampleRate fromValue( int value ) + { + List rates = mController.getSampleRates(); + + for( AirspySampleRate rate: rates ) + { + if( rate.getRate() == value ) + { + return rate; + } + } + + if( rates.size() > 0 ) + { + return rates.get( 0 ); + } + + return null; + } + + /** + * Sets all controls to the argument enabled state + */ + private void setControlsEnabled( boolean enabled ) + { + if( mConfigurationName.isEnabled() != enabled ) + { + mConfigurationName.setEnabled( enabled ); + } + + if( mTunerInfo.isEnabled() != enabled ) + { + mTunerInfo.setEnabled( enabled ); + } + + if( mSampleRateCombo.isEnabled() != enabled ) + { + mSampleRateCombo.setEnabled( enabled ); + } + + if( mFrequencyCorrection.isEnabled() != enabled ) + { + mFrequencyCorrection.setEnabled( enabled ); + } + + if( mGainModeCombo.isEnabled() != enabled ) + { + mGainModeCombo.setEnabled( enabled ); + } + + if( mMasterGain.isEnabled() != enabled ) + { + mMasterGain.setEnabled( enabled ); + } + + if( mIFGain.isEnabled() != enabled ) + { + mIFGain.setEnabled( enabled ); + } + + if( mMixerGain.isEnabled() != enabled ) + { + mMixerGain.setEnabled( enabled ); + } + + if( mMixerAGC.isEnabled() != enabled ) + { + mMixerAGC.setEnabled( enabled ); + } + + if( mLNAGain.isEnabled() != enabled ) + { + mLNAGain.setEnabled( enabled ); + } + + if( mLNAAGC.isEnabled() != enabled ) + { + mLNAAGC.setEnabled( enabled ); + } + } + + /** + * Applies the tuner configuration to the editor. If the configuration is assigned to the + * currently selected tuner, then the settings are applied. + */ + @Override + public void setItem( TunerConfiguration config ) + { + super.setItem( config ); + + if( hasItem() && getItem().isAssigned() ) + { + AirspyTunerConfiguration airspy = getConfiguration(); + + setControlsEnabled( true ); + + mConfigurationName.setText( airspy.getName() ); + + AirspySampleRate rate = fromValue( airspy.getSampleRate() ); + + if( rate != null ) + { + mSampleRateCombo.setSelectedItem( rate ); + } + + mFrequencyCorrection.setValue( airspy.getFrequencyCorrection() ); + + GainMode mode = Gain.getGainMode( airspy.getGain() ); + + //This will set the master, IF, Mixer, LNA and AGC controls + mGainModeCombo.setSelectedItem( mode ); + } + else + { + setControlsEnabled( false ); + mConfigurationName.setText( hasItem() ? getItem().getName() : "" ); + } + } + + private String getTunerInfo() + { + StringBuilder sb = new StringBuilder(); + + AirspyDeviceInformation info = mController.getDeviceInfo(); + + sb.append( "

Airspy Tuner

" ); + sb.append( "Serial: " ); + sb.append( info.getSerialNumber() ); + sb.append( "
" ); + + sb.append( "Firmware: " ); + String[] firmware = info.getVersion().split( " " ); + sb.append( firmware.length > 1 ? firmware[ 0 ] : info.getVersion() ); + sb.append( "
" ); + + sb.append( "Part: " ); + sb.append( info.getPartNumber() ); + sb.append( "
" ); + + sb.append( "Board ID: " ); + sb.append( info.getBoardID().getLabel() ); + sb.append( "
" ); + + return sb.toString(); + } +} diff --git a/src/source/tuner/airspy/AirspyTunerEditorPanel.java b/src/source/tuner/airspy/AirspyTunerEditorPanel.java deleted file mode 100644 index 3cc93d89..00000000 --- a/src/source/tuner/airspy/AirspyTunerEditorPanel.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * SDR Trunk - * Copyright (C) 2015 Dennis Sheirer - * - * 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, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - ******************************************************************************/ -package source.tuner.airspy; - -import gui.control.JFrequencyControl; - -import java.awt.Color; - -import javax.swing.JLabel; -import javax.swing.JPanel; - -import net.miginfocom.swing.MigLayout; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import settings.SettingsManager; -import source.SourceException; -import source.tuner.frequency.FrequencyChangeEvent; -import source.tuner.frequency.FrequencyChangeEvent.Event; -import source.tuner.frequency.IFrequencyChangeProcessor; - -import com.jidesoft.swing.JideTabbedPane; - -public class AirspyTunerEditorPanel extends JPanel - implements IFrequencyChangeProcessor -{ - private static final long serialVersionUID = 1L; - - private final static Logger mLog = - LoggerFactory.getLogger( AirspyTunerEditorPanel.class ); - - private JFrequencyControl mFrequencyControl; - - private AirspyTuner mTuner; - private AirspyTunerController mController; - private SettingsManager mSettingsManager; - - public AirspyTunerEditorPanel( AirspyTuner tuner, - SettingsManager settingsManager ) - { - mTuner = tuner; - mController = mTuner.getController(); - mSettingsManager = settingsManager; - - initGUI(); - } - - private void initGUI() - { - setLayout( new MigLayout( "fill,wrap 2", - "[right,grow][grow]", - "[][][][][][grow]" ) ); - - add( new JLabel( "Airspy Tuner" ), "span,align center" ); - - mFrequencyControl = new JFrequencyControl(); - - mFrequencyControl.addListener( this ); - - /* Add frequency control as frequency change listener. This creates a - * feedback loop, so the control does not rebroadcast the event */ - mTuner.getTunerController().addListener( mFrequencyControl ); - - mFrequencyControl.setFrequency( mController.getFrequency(), false ); - - add( mFrequencyControl, "span,align center" ); - - JideTabbedPane tabs = new JideTabbedPane(); - tabs.setFont( this.getFont() ); - tabs.setForeground( Color.BLACK ); - - add( tabs, "span,grow,push" ); - - tabs.add( "Config", new AirspyTunerConfigurationPanel( - mSettingsManager, mTuner.getController() ) ); - - tabs.add( "Info", new AirspyInformationPanel( mTuner.getController() ) ); - } - - @Override - public void frequencyChanged( FrequencyChangeEvent event ) - { - if( event.getEvent() == Event.NOTIFICATION_FREQUENCY_CHANGE ) - { - try - { - mController.setFrequency( event.getValue().longValue() ); - } - catch ( SourceException e ) - { - mLog.error( "error setting frequency [" + - event.getValue().longValue() + "]", e ); - } - } - } -} diff --git a/src/source/tuner/configuration/TunerConfigurationEditor.java b/src/source/tuner/configuration/TunerConfigurationEditor.java index 2c0908c5..1c02f4b0 100644 --- a/src/source/tuner/configuration/TunerConfigurationEditor.java +++ b/src/source/tuner/configuration/TunerConfigurationEditor.java @@ -1,7 +1,6 @@ package source.tuner.configuration; import gui.editor.Editor; -import source.tuner.TunerType; public abstract class TunerConfigurationEditor extends Editor { @@ -14,8 +13,6 @@ public abstract class TunerConfigurationEditor extends Editor mComboMasterGain; private JComboBox mComboMixerGain; @@ -84,12 +88,6 @@ public class R820TTunerEditor extends TunerConfigurationEditor init(); } - @Override - public boolean canEdit( TunerType tunerType ) - { - return tunerType == TunerType.RAFAELMICRO_R820T; - } - @Override public void save() { @@ -169,6 +167,11 @@ public class R820TTunerEditor extends TunerConfigurationEditor mConfigurationName.setEnabled( enabled ); } + if( mTunerInfo.isEnabled() != enabled ) + { + mTunerInfo.setEnabled( enabled ); + } + if( mFrequencyCorrection.isEnabled() != enabled ) { mFrequencyCorrection.setEnabled( enabled ); @@ -213,9 +216,9 @@ public class R820TTunerEditor extends TunerConfigurationEditor private void init() { setLayout( new MigLayout( "fill,wrap 4", "[right][grow,fill][right][grow,fill]", - "[][][][][][][grow]" ) ); + "[][][][][][][][grow]" ) ); - add( new JLabel( "R820T Tuner Configuration" ), "span, align center" ); + add( new JLabel( "R820T Tuner Configuration" ), "span,align center" ); /** * Tuner Configuration Name @@ -234,7 +237,21 @@ public class R820TTunerEditor extends TunerConfigurationEditor } ); add( new JLabel( "Name:" ) ); - add( mConfigurationName, "span,grow" ); + add( mConfigurationName, "span 2" ); + + mTunerInfo = new JButton( "Tuner Info" ); + mTunerInfo.setEnabled( false ); + mTunerInfo.addActionListener( new ActionListener() + { + @Override + public void actionPerformed( ActionEvent e ) + { + JOptionPane.showMessageDialog( R820TTunerEditor.this, getTunerInfo(), + "Tuner Info", JOptionPane.INFORMATION_MESSAGE ); + } + } ); + add( mTunerInfo ); + mComboSampleRate = new JComboBox<>( SampleRate.values() ); mComboSampleRate.setEnabled( false ); @@ -312,10 +329,12 @@ public class R820TTunerEditor extends TunerConfigurationEditor add( mFrequencyCorrection ); add( new JSeparator( JSeparator.HORIZONTAL ), "span,grow" ); - + /** * Gain Controls */ + add( new JLabel( "Gain" ), "span" ); + /* Master Gain Control */ mComboMasterGain = new JComboBox( R820TGain.values() ); mComboMasterGain.setEnabled( false ); @@ -500,4 +519,48 @@ public class R820TTunerEditor extends TunerConfigurationEditor add( new JLabel( "VGA:" ) ); add( mComboVGAGain ); } + + private String getTunerInfo() + { + StringBuilder sb = new StringBuilder(); + + Descriptor descriptor = mController.getDescriptor(); + + sb.append( "

RTL-2832 with R820T Tuner

" ); + + if( descriptor == null ) + { + sb.append( "No EEPROM Descriptor Available" ); + } + else + { + sb.append( "USB ID: " ); + sb.append( descriptor.getVendorID() ); + sb.append( ":" ); + sb.append( descriptor.getProductID() ); + sb.append( "
" ); + + sb.append( "Vendor: " ); + sb.append( descriptor.getVendorLabel() ); + sb.append( "
" ); + + sb.append( "Product: " ); + sb.append( descriptor.getProductLabel() ); + sb.append( "
" ); + + sb.append( "Serial: " ); + sb.append( descriptor.getSerial() ); + sb.append( "
" ); + + sb.append( "IR Enabled: " ); + sb.append( descriptor.irEnabled() ); + sb.append( "
" ); + + sb.append( "Remote Wake: " ); + sb.append( descriptor.remoteWakeupEnabled() ); + sb.append( "
" ); + } + + return sb.toString(); + } }