Resolves #170 adding support for Airspy Mini tuner's 3 and 6 MHz

sample rates.

Resolves issue in PolyphaseChannelManager responding to sample rate
changes in the tuner.  The manager now recreates the channelizer when
needed if the tuner's sample rate has changed since the last time the
channelizer was used.

Updates the Tuner selection view to reflect tuner lock state.  Updates
the tuner editors to enable/disable frequency controller and sample
rate controls according to the tuner's lock state.
This commit is contained in:
Denny
2018-07-14 07:45:42 -04:00
parent 9e7fa7618d
commit 104c4f72be
18 changed files with 376 additions and 348 deletions

View File

@@ -65,6 +65,10 @@ public abstract class Tuner implements ISourceEventProcessor
case NOTIFICATION_SAMPLE_RATE_CHANGE:
broadcast(new TunerEvent(Tuner.this, Event.SAMPLE_RATE));
break;
case NOTIFICATION_FREQUENCY_AND_SAMPLE_RATE_LOCKED:
case NOTIFICATION_FREQUENCY_AND_SAMPLE_RATE_UNLOCKED:
broadcast(new TunerEvent(Tuner.this, Event.LOCK_STATE_CHANGE));
break;
default:
break;
}

View File

@@ -2,33 +2,34 @@ package io.github.dsheirer.source.tuner;
public class TunerEvent
{
private Tuner mTuner;
private Event mEvent;
public TunerEvent( Tuner tuner, Event event )
{
mTuner = tuner;
mEvent = event;
}
public Tuner getTuner()
{
return mTuner;
}
private Tuner mTuner;
private Event mEvent;
public Event getEvent()
{
return mEvent;
}
public enum Event
{
ADD,
REMOVE,
CHANNEL_COUNT,
FREQUENCY,
SAMPLE_RATE,
REQUEST_MAIN_SPECTRAL_DISPLAY,
REQUEST_NEW_SPECTRAL_DISPLAY;
}
public TunerEvent(Tuner tuner, Event event)
{
mTuner = tuner;
mEvent = event;
}
public Tuner getTuner()
{
return mTuner;
}
public Event getEvent()
{
return mEvent;
}
public enum Event
{
ADD,
LOCK_STATE_CHANGE,
REMOVE,
CHANNEL_COUNT,
FREQUENCY,
SAMPLE_RATE,
REQUEST_MAIN_SPECTRAL_DISPLAY,
REQUEST_NEW_SPECTRAL_DISPLAY;
}
}

View File

@@ -257,7 +257,16 @@ public class TunerModel extends AbstractTableModel implements Listener<TunerEven
return 0;
}
case CHANNEL_COUNT:
return tuner.getChannelSourceManager().getTunerChannelCount();
int channelCount = tuner.getChannelSourceManager().getTunerChannelCount();
if(channelCount > 0)
{
return channelCount + " (LOCKED)";
}
else
{
return "0";
}
case SPECTRAL_DISPLAY_MAIN:
return "Main";
case SPECTRAL_DISPLAY_NEW:

View File

@@ -1,17 +1,17 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-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 <http://www.gnu.org/licenses/>
******************************************************************************/
@@ -19,18 +19,27 @@
package io.github.dsheirer.source.tuner;
import com.jidesoft.swing.JideSplitPane;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.source.tuner.TunerEvent.Event;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
@@ -38,129 +47,150 @@ import java.util.List;
public class TunerViewPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( TunerViewPanel.class );
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger(TunerViewPanel.class);
private TunerModel mTunerModel;
private JTable mTunerTable;
private TableRowSorter<TunerModel> mRowSorter;
private JideSplitPane mSplitPane;
private TunerEditor mTunerEditor;
public TunerViewPanel( TunerModel tunerModel )
{
mTunerModel = tunerModel;
mTunerEditor = new TunerEditor( mTunerModel.getTunerConfigurationModel() );
init();
}
private void init()
{
setLayout( new MigLayout( "insets 0 0 0 0", "[fill,grow]", "[fill,grow]" ) );
private TunerModel mTunerModel;
private JTable mTunerTable;
private TableRowSorter<TunerModel> mRowSorter;
private JideSplitPane mSplitPane;
private TunerEditor mTunerEditor;
mRowSorter = new TableRowSorter<>( mTunerModel );
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
sortKeys.add( new RowSorter.SortKey( TunerModel.TUNER_TYPE, SortOrder.ASCENDING ) );
sortKeys.add( new RowSorter.SortKey( TunerModel.TUNER_ID, SortOrder.ASCENDING ) );
mRowSorter.setSortKeys( sortKeys );
mTunerTable = new JTable( mTunerModel );
mTunerTable.setRowSorter( mRowSorter );
mTunerTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
mTunerTable.getSelectionModel().addListSelectionListener( new ListSelectionListener()
{
@Override
public void valueChanged( ListSelectionEvent event )
{
if( !event.getValueIsAdjusting() )
{
int row = mTunerTable.getSelectedRow();
int modelRow = mTunerTable.convertRowIndexToModel( row );
public TunerViewPanel(TunerModel tunerModel)
{
mTunerModel = tunerModel;
mTunerEditor = new TunerEditor(mTunerModel.getTunerConfigurationModel());
mTunerEditor.setItem( mTunerModel.getTuner( modelRow ) );
}
}
} );
mTunerTable.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
int column = mTunerTable.columnAtPoint( e.getPoint() );
init();
}
if( column == TunerModel.SPECTRAL_DISPLAY_MAIN )
{
int tableRow = mTunerTable.rowAtPoint( e.getPoint() );
int modelRow = mTunerTable.convertRowIndexToModel( tableRow );
Tuner tuner = mTunerModel.getTuner( modelRow );
if( tuner != null )
{
mTunerModel.broadcast( new TunerEvent( tuner,
Event.REQUEST_MAIN_SPECTRAL_DISPLAY ) );
}
}
else if( column == TunerModel.SPECTRAL_DISPLAY_NEW )
{
int tableRow = mTunerTable.rowAtPoint( e.getPoint() );
int modelRow = mTunerTable.convertRowIndexToModel( tableRow );
Tuner tuner = mTunerModel.getTuner( modelRow );
if( tuner != null )
{
mTunerModel.broadcast( new TunerEvent( tuner,
Event.REQUEST_NEW_SPECTRAL_DISPLAY ) );
}
}
}
} );
TableCellRenderer renderer = new LinkCellRenderer();
mTunerTable.getColumnModel().getColumn( 5 ).setCellRenderer( renderer );
mTunerTable.getColumnModel().getColumn( 6 ).setCellRenderer( renderer );
JScrollPane listScroller = new JScrollPane( mTunerTable );
listScroller.setPreferredSize( new Dimension( 400, 20 ) );
private void init()
{
setLayout(new MigLayout("insets 0 0 0 0", "[fill,grow]", "[fill,grow]"));
JScrollPane editorScroller = new JScrollPane( mTunerEditor );
editorScroller.setPreferredSize( new Dimension( 400, 80 ) );
mSplitPane = new JideSplitPane();
mSplitPane.setOrientation( JideSplitPane.VERTICAL_SPLIT );
mSplitPane.add( listScroller );
mSplitPane.add( editorScroller );
add( mSplitPane );
}
public class LinkCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
mRowSorter = new TableRowSorter<>(mTunerModel);
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
sortKeys.add(new RowSorter.SortKey(TunerModel.TUNER_TYPE, SortOrder.ASCENDING));
sortKeys.add(new RowSorter.SortKey(TunerModel.TUNER_ID, SortOrder.ASCENDING));
mRowSorter.setSortKeys(sortKeys);
@Override
public Component getTableCellRendererComponent( JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column )
{
JLabel label = (JLabel)super.getTableCellRendererComponent( table,
value, isSelected, hasFocus, row, column );
label.setForeground( Color.BLUE.brighter() );
if( column == TunerModel.SPECTRAL_DISPLAY_MAIN )
{
label.setToolTipText( "Show this tuner in the main spectral display" );
}
else if( column == TunerModel.SPECTRAL_DISPLAY_NEW )
{
label.setToolTipText( "Show this tuner in a new spectral display" );
}
return label;
}
}
mTunerTable = new JTable(mTunerModel);
mTunerTable.setRowSorter(mRowSorter);
mTunerTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
mTunerTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent event)
{
if(!event.getValueIsAdjusting())
{
int row = mTunerTable.getSelectedRow();
int modelRow = mTunerTable.convertRowIndexToModel(row);
mTunerEditor.setItem(mTunerModel.getTuner(modelRow));
}
}
});
mTunerModel.addListener(new Listener<TunerEvent>()
{
@Override
public void receive(TunerEvent tunerEvent)
{
switch(tunerEvent.getEvent())
{
case LOCK_STATE_CHANGE:
int row = mTunerTable.getSelectedRow();
if(row >= 0)
{
int modelRow = mTunerTable.convertRowIndexToModel(row);
mTunerEditor.setItem(mTunerModel.getTuner(modelRow));
}
break;
}
}
});
mTunerTable.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
int column = mTunerTable.columnAtPoint(e.getPoint());
if(column == TunerModel.SPECTRAL_DISPLAY_MAIN)
{
int tableRow = mTunerTable.rowAtPoint(e.getPoint());
int modelRow = mTunerTable.convertRowIndexToModel(tableRow);
Tuner tuner = mTunerModel.getTuner(modelRow);
if(tuner != null)
{
mTunerModel.broadcast(new TunerEvent(tuner,
Event.REQUEST_MAIN_SPECTRAL_DISPLAY));
}
}
else if(column == TunerModel.SPECTRAL_DISPLAY_NEW)
{
int tableRow = mTunerTable.rowAtPoint(e.getPoint());
int modelRow = mTunerTable.convertRowIndexToModel(tableRow);
Tuner tuner = mTunerModel.getTuner(modelRow);
if(tuner != null)
{
mTunerModel.broadcast(new TunerEvent(tuner,
Event.REQUEST_NEW_SPECTRAL_DISPLAY));
}
}
}
});
TableCellRenderer renderer = new LinkCellRenderer();
mTunerTable.getColumnModel().getColumn(5).setCellRenderer(renderer);
mTunerTable.getColumnModel().getColumn(6).setCellRenderer(renderer);
JScrollPane listScroller = new JScrollPane(mTunerTable);
listScroller.setPreferredSize(new Dimension(400, 20));
JScrollPane editorScroller = new JScrollPane(mTunerEditor);
editorScroller.setPreferredSize(new Dimension(400, 80));
mSplitPane = new JideSplitPane();
mSplitPane.setOrientation(JideSplitPane.VERTICAL_SPLIT);
mSplitPane.add(listScroller);
mSplitPane.add(editorScroller);
add(mSplitPane);
}
public class LinkCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column)
{
JLabel label = (JLabel)super.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
label.setForeground(Color.BLUE.brighter());
if(column == TunerModel.SPECTRAL_DISPLAY_MAIN)
{
label.setToolTipText("Show this tuner in the main spectral display");
}
else if(column == TunerModel.SPECTRAL_DISPLAY_NEW)
{
label.setToolTipText("Show this tuner in a new spectral display");
}
return label;
}
}
}

View File

@@ -80,8 +80,7 @@ public class AirspyTunerController extends USBTunerController
public static final long FREQUENCY_MAX = 1800000000l;
public static final long FREQUENCY_DEFAULT = 101100000;
public static final double USABLE_BANDWIDTH_PERCENT = 0.90;
public static final AirspySampleRate DEFAULT_SAMPLE_RATE =
new AirspySampleRate(0, 10000000, "10.00 MHz");
public static final AirspySampleRate DEFAULT_SAMPLE_RATE = new AirspySampleRate(0, 10000000, "10.00 MHz");
private static final long USB_TIMEOUT_MS = 2000l; //milliseconds
private static final byte USB_INTERFACE = (byte) 0x0;
@@ -168,7 +167,7 @@ public class AirspyTunerController extends USBTunerController
try
{
setSampleRate(DEFAULT_SAMPLE_RATE);
setSampleRate(mSampleRates.get(0));
}
catch(IllegalArgumentException | LibUsbException | UsbException e)
{
@@ -292,8 +291,7 @@ public class AirspyTunerController extends USBTunerController
}
catch(UsbException e)
{
throw new SourceException("Couldn't set sample rate [" +
rate.toString() + "]", e);
throw new SourceException("Couldn't set sample rate [" + rate.toString() + "]", e);
}
try
@@ -314,8 +312,7 @@ public class AirspyTunerController extends USBTunerController
}
catch(Exception e)
{
throw new SourceException("Couldn't apply gain settings from "
+ "airspy config", e);
throw new SourceException("Couldn't apply gain settings from airspy config", e);
}
try
@@ -389,8 +386,7 @@ public class AirspyTunerController extends USBTunerController
* is not supported by the current firmware
* @throws UsbException if there was a USB error
*/
public void setSampleRate(AirspySampleRate rate) throws
LibUsbException, UsbException, SourceException
public void setSampleRate(AirspySampleRate rate) throws LibUsbException, UsbException, SourceException
{
if(rate.getRate() != mSampleRate)
{
@@ -398,8 +394,7 @@ public class AirspyTunerController extends USBTunerController
if(result != 1)
{
throw new UsbException("Error setting sample rate [" +
rate + "] rate - return value [" + result + "]");
throw new UsbException("Error setting sample rate [" + rate + "] rate - return value [" + result + "]");
}
else
{
@@ -607,8 +602,7 @@ public class AirspyTunerController extends USBTunerController
* Queries the device for available sample rates. Will always provide at
* least the default 10 MHz sample rate.
*/
private void determineAvailableSampleRates()
throws LibUsbException, UsbException
private void determineAvailableSampleRates() throws LibUsbException, UsbException
{
mSampleRates.clear();
@@ -629,7 +623,6 @@ public class AirspyTunerController extends USBTunerController
for(int x = 0; x < count; x++)
{
int rate = EndianUtils.readSwappedInteger(rawRates, (x * 4));
mSampleRates.add(new AirspySampleRate(x, rate, formatSampleRate(rate)));
}
}

View File

@@ -43,7 +43,6 @@ import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.usb.UsbException;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@@ -55,8 +54,7 @@ public class AirspyTunerEditor extends TunerConfigurationEditor
{
private static final long serialVersionUID = 1L;
private final static Logger mLog =
LoggerFactory.getLogger(AirspyTunerEditor.class);
private final static Logger mLog = LoggerFactory.getLogger(AirspyTunerEditor.class);
private JTextField mConfigurationName;
private JButton mTunerInfo;
@@ -103,24 +101,6 @@ public class AirspyTunerEditor extends TunerConfigurationEditor
return null;
}
/**
* Updates the enabled state of the sample rate combo control.
*
* @param enabled state for the sample rate control
*/
@Override
public void setSampleRateControl(boolean enabled)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mSampleRateCombo.setEnabled(enabled);
}
});
}
private void init()
{
setLayout(new MigLayout("fill,wrap 4", "[right][grow,fill][right][grow,fill]",
@@ -616,6 +596,21 @@ public class AirspyTunerEditor extends TunerConfigurationEditor
return null;
}
/**
* Updates the sample rate tooltip according to the tuner controller's lock state.
*/
private void updateSampleRateToolTip()
{
if(mController.isLocked())
{
mSampleRateCombo.setToolTipText("Sample Rate is locked. Disable decoding channels to unlock.");
}
else
{
mSampleRateCombo.setToolTipText("Select a sample rate for the tuner");
}
}
/**
* Sets all controls to the argument enabled state
*/
@@ -631,7 +626,13 @@ public class AirspyTunerEditor extends TunerConfigurationEditor
mTunerInfo.setEnabled(enabled);
}
if(mSampleRateCombo.isEnabled() != enabled)
updateSampleRateToolTip();
if(mController.isLocked())
{
mSampleRateCombo.setEnabled(false);
}
else if(mSampleRateCombo.isEnabled() != enabled)
{
mSampleRateCombo.setEnabled(enabled);
}

View File

@@ -32,12 +32,4 @@ public abstract class TunerConfigurationEditor extends Editor<TunerConfiguration
{
return mTunerConfigurationModel;
}
/**
* Sets the state of the sample rate editor control. When enabled, users are allowed to change the sample rate
* of the tuner. When disabled, user controls should NOT allow sample rate changes.
*
* @param enabled state for the sample rate control
*/
public abstract void setSampleRateControl(boolean enabled);
}

View File

@@ -86,12 +86,6 @@ public class FCD1TunerEditor extends TunerConfigurationEditor
return null;
}
@Override
public void setSampleRateControl(boolean enabled)
{
//no-op
}
private void init()
{
setLayout(new MigLayout("fill,wrap 4", "[right][grow,fill][right][grow,fill]",

View File

@@ -76,12 +76,6 @@ public class FCD2TunerEditor extends TunerConfigurationEditor
return null;
}
@Override
public void setSampleRateControl(boolean enabled)
{
//no-op
}
private void init()
{
setLayout(new MigLayout("fill,wrap 4", "[right][grow,fill][right][grow,fill]",

View File

@@ -22,8 +22,8 @@ import io.github.dsheirer.source.SourceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class FrequencyController
{
@@ -38,7 +38,7 @@ public class FrequencyController
private double mSampleRate = 0.0d;
private boolean mLocked = false;
private List<ISourceEventProcessor> mProcessors = new ArrayList<>();
private List<ISourceEventProcessor> mProcessors = new CopyOnWriteArrayList<>();
public FrequencyController(Tunable tunable, long minFrequency, long maxFrequency, double frequencyCorrection)
{
@@ -95,9 +95,16 @@ public class FrequencyController
*/
public void setSampleRate(int sampleRate) throws SourceException
{
mSampleRate = sampleRate;
if(!mLocked)
{
mSampleRate = sampleRate;
broadcastSampleRateChange();
broadcastSampleRateChange();
}
else
{
mLog.warn("Cannot change sample rate while tuner is is LOCKED state.");
}
}
/**
@@ -108,6 +115,17 @@ public class FrequencyController
return mSampleRate;
}
/**
* Indicates if the specified frequency can be tuned (ie is within min/max frequency) by this controller.
*
* @param frequency to evaluate
* @return true if the frequency falls within the tuning range of this controller
*/
public boolean canTune(long frequency)
{
return getMinimumFrequency() <= frequency && frequency <= getMaximumFrequency();
}
/**
* Get frequency in hertz
*/
@@ -128,17 +146,6 @@ public class FrequencyController
setFrequency(frequency, true);
}
/**
* Indicates if the specified frequency can be tuned (ie is within min/max frequency) by this controller.
*
* @param frequency to evaluate
* @return true if the frequency falls within the tuning range of this controller
*/
public boolean canTune(long frequency)
{
return getMinimumFrequency() <= frequency && frequency <= getMaximumFrequency();
}
/**
* Set frequency with optional broadcast of frequency change event. This
* method supports changing the frequency correction value without

View File

@@ -41,7 +41,6 @@ import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.usb.UsbException;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@@ -84,19 +83,6 @@ public class HackRFTunerEditor extends TunerConfigurationEditor
return null;
}
@Override
public void setSampleRateControl(boolean enabled)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mComboSampleRate.setEnabled(enabled);
}
});
}
private void init()
{
setLayout(new MigLayout("fill,wrap 4", "[right][grow,fill][right][grow,fill]",
@@ -297,6 +283,21 @@ public class HackRFTunerEditor extends TunerConfigurationEditor
add(mComboVGAGain);
}
/**
* Updates the sample rate tooltip according to the tuner controller's lock state.
*/
private void updateSampleRateToolTip()
{
if(mController.isLocked())
{
mComboSampleRate.setToolTipText("Sample Rate is locked. Disable decoding channels to unlock.");
}
else
{
mComboSampleRate.setToolTipText("Select a sample rate for the tuner");
}
}
/**
* Sets each of the tuner configuration controls to the enabled argument state
*/
@@ -317,7 +318,13 @@ public class HackRFTunerEditor extends TunerConfigurationEditor
mFrequencyCorrection.setEnabled(enabled);
}
if(mComboSampleRate.isEnabled() != enabled)
updateSampleRateToolTip();
if(mController.isLocked())
{
mComboSampleRate.setEnabled(false);
}
else if(mComboSampleRate.isEnabled() != enabled)
{
mComboSampleRate.setEnabled(enabled);
}

View File

@@ -45,7 +45,6 @@ import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.usb.UsbException;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@@ -88,19 +87,6 @@ public class E4KTunerEditor extends TunerConfigurationEditor
return null;
}
@Override
public void setSampleRateControl(boolean enabled)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mComboSampleRate.setEnabled(enabled);
}
});
}
private void init()
{
setLayout(new MigLayout("fill,wrap 4", "[right][grow,fill][right][grow,fill]",
@@ -354,6 +340,21 @@ public class E4KTunerEditor extends TunerConfigurationEditor
add(mComboEnhanceGain);
}
/**
* Updates the sample rate tooltip according to the tuner controller's lock state.
*/
private void updateSampleRateToolTip()
{
if(mController.isLocked())
{
mComboSampleRate.setToolTipText("Sample Rate is locked. Disable decoding channels to unlock.");
}
else
{
mComboSampleRate.setToolTipText("Select a sample rate for the tuner");
}
}
/**
* Sets each of the tuner configuration controls to the enabled argument state
*/
@@ -374,7 +375,13 @@ public class E4KTunerEditor extends TunerConfigurationEditor
mFrequencyCorrection.setEnabled(enabled);
}
if(mComboSampleRate.isEnabled() != enabled)
updateSampleRateToolTip();
if(mController.isLocked())
{
mComboSampleRate.setEnabled(false);
}
else if(mComboSampleRate.isEnabled() != enabled)
{
mComboSampleRate.setEnabled(enabled);
}

View File

@@ -45,7 +45,6 @@ import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.usb.UsbException;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@@ -89,19 +88,6 @@ public class R820TTunerEditor extends TunerConfigurationEditor
return null;
}
@Override
public void setSampleRateControl(boolean enabled)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mComboSampleRate.setEnabled(enabled);
}
});
}
private void init()
{
setLayout(new MigLayout("fill,wrap 4", "[right][grow,fill][right][grow,fill]",
@@ -408,6 +394,21 @@ public class R820TTunerEditor extends TunerConfigurationEditor
add(mComboVGAGain);
}
/**
* Updates the sample rate tooltip according to the tuner controller's lock state.
*/
private void updateSampleRateToolTip()
{
if(mController.isLocked())
{
mComboSampleRate.setToolTipText("Sample Rate is locked. Disable decoding channels to unlock.");
}
else
{
mComboSampleRate.setToolTipText("Select a sample rate for the tuner");
}
}
/**
* Sets each of the tuner configuration controls to the enabled argument state
*/
@@ -428,7 +429,13 @@ public class R820TTunerEditor extends TunerConfigurationEditor
mFrequencyCorrection.setEnabled(enabled);
}
if(mComboSampleRate.isEnabled() != enabled)
updateSampleRateToolTip();
if(mController.isLocked())
{
mComboSampleRate.setEnabled(false);
}
else if(mComboSampleRate.isEnabled() != enabled)
{
mComboSampleRate.setEnabled(enabled);
}