Merge pull request #327 from DSheirer/321-channel-preferred-tuner

321 channel preferred tuner
This commit is contained in:
Denny Sheirer
2018-02-09 07:13:13 -05:00
committed by GitHub
6 changed files with 345 additions and 67 deletions

104
sdr-trunk.ipr Normal file
View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac"/>
<resourceExtensions>
<entry name=".+\.(properties|xml|html|dtd|tld)"/>
<entry name=".+\.(gif|png|jpeg|jpg)"/>
</resourceExtensions>
<wildcardResourcePatterns>
<entry name="!?*.class"/>
<entry name="!?*.scala"/>
<entry name="!?*.java"/>
<entry name="!?*.groovy"/>
</wildcardResourcePatterns>
<annotationProcessing enabled="false" useClasspath="true"/>
<bytecodeTargetLevel target="1.8"/>
</component>
<component name="CopyrightManager" default="">
<module2copyright/>
</component>
<component name="DependencyValidationManager">
<option name="SKIP_IMPORT_STATEMENTS" value="false"/>
</component>
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false"/>
<component name="GradleUISettings">
<setting name="root"/>
</component>
<component name="GradleUISettings2">
<setting name="root"/>
</component>
<component name="IdProvider" IDEtalkID="11DA1DB66DD62DDA1ED602B7079FE97C"/>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY"/>
<option name="OPTION_SCOPE" value="protected"/>
<option name="OPTION_HIERARCHY" value="true"/>
<option name="OPTION_NAVIGATOR" value="true"/>
<option name="OPTION_INDEX" value="true"/>
<option name="OPTION_SEPARATE_INDEX" value="true"/>
<option name="OPTION_DOCUMENT_TAG_USE" value="false"/>
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false"/>
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false"/>
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true"/>
<option name="OPTION_DEPRECATED_LIST" value="true"/>
<option name="OTHER_OPTIONS" value=""/>
<option name="HEAP_SIZE"/>
<option name="LOCALE"/>
<option name="OPEN_IN_BROWSER" value="true"/>
</component>
<component name="ProjectModuleManager">
<modules>
<module filepath="$PROJECT_DIR$/sdr-trunk.iml" fileurl="file://$PROJECT_DIR$/sdr-trunk.iml"/>
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" assert-keyword="true" jdk-15="true" project-jdk-type="JavaSDK" assert-jdk-15="true" project-jdk-name="1.8">
<output url="file://$PROJECT_DIR$/out"/>
</component>
<component name="SvnBranchConfigurationManager">
<option name="mySupportsUserInfoFilter" value="true"/>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs=""/>
</component>
<component name="masterDetails">
<states>
<state key="ArtifactsStructureConfigurable.UI">
<UIState>
<splitter-proportions>
<SplitterProportionsDataImpl/>
</splitter-proportions>
<settings/>
</UIState>
</state>
<state key="Copyright.UI">
<UIState>
<splitter-proportions>
<SplitterProportionsDataImpl/>
</splitter-proportions>
</UIState>
</state>
<state key="ProjectJDKs.UI">
<UIState>
<splitter-proportions>
<SplitterProportionsDataImpl>
<option name="proportions">
<list>
<option value="0.2"/>
</list>
</option>
</SplitterProportionsDataImpl>
</splitter-proportions>
<last-edited>1.6</last-edited>
</UIState>
</state>
<state key="ScopeChooserConfigurable.UI">
<UIState>
<splitter-proportions>
<SplitterProportionsDataImpl/>
</splitter-proportions>
<settings/>
</UIState>
</state>
</states>
</component>
</project>

View File

@@ -25,7 +25,8 @@ import io.github.dsheirer.source.mixer.MixerSourceEditor;
import io.github.dsheirer.source.tuner.TunerSourceEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -43,7 +44,7 @@ public class SourceConfigurationEditor extends Editor<Channel>
mMixerSourceEditor = new MixerSourceEditor( sourceManager );
mMixerSourceEditor.setSaveRequestListener( this );
mTunerSourceEditor = new TunerSourceEditor();
mTunerSourceEditor = new TunerSourceEditor(sourceManager.getTunerModel());
mTunerSourceEditor.setSaveRequestListener( this );
init();

View File

@@ -59,6 +59,11 @@ public class SourceManager
return mTunerManager;
}
public TunerModel getTunerModel()
{
return mTunerModel;
}
public Source getSource(SourceConfiguration config, int bandwidth)
throws SourceException
{

View File

@@ -1,6 +1,6 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 Dennis Sheirer
* Copyright (C) 2014-2018 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
@@ -33,6 +33,7 @@ public class SourceConfigTuner extends SourceConfiguration
private long mFrequency = 0;
private int mBandwidth = 12500;
private String mPreferredTuner;
public SourceConfigTuner()
{
@@ -58,6 +59,34 @@ public class SourceConfigTuner extends SourceConfiguration
mFrequency = frequency;
}
/**
* Preferred tuner to use for this configuration.
* @return tuner name or null
*/
@JacksonXmlProperty(isAttribute = true, localName = "preferred_tuner")
public String getPreferredTuner()
{
return mPreferredTuner;
}
/**
* Indicates if this configuration has a specified preferred tuner
*/
@JsonIgnore
public boolean hasPreferredTuner()
{
return mPreferredTuner != null;
}
/**
* Specifies the preferred tuner to use for this configuration
* @param preferredTuner to use, if available
*/
public void setPreferredTuner(String preferredTuner)
{
mPreferredTuner = preferredTuner;
}
@JsonIgnore
@Override
public String getDescription()

View File

@@ -70,6 +70,28 @@ public class TunerModel extends AbstractTableModel implements Listener<TunerEven
return null;
}
/**
* Find a tuner that matches the name argument
*
* @param name of the tuner
* @return named tuner or null
*/
public Tuner getTuner(String name)
{
if(name != null)
{
for(Tuner tuner: mTuners)
{
if(tuner.getName().equalsIgnoreCase(name))
{
return tuner;
}
}
}
return null;
}
public void addTuners( List<Tuner> Tuners )
{
for( Tuner tuner: Tuners )
@@ -270,6 +292,31 @@ public class TunerModel extends AbstractTableModel implements Listener<TunerEven
Iterator<Tuner> it = mTuners.iterator();
Tuner tuner;
if(config.hasPreferredTuner())
{
tuner = getTuner(config.getPreferredTuner());
if(tuner != null)
{
try
{
retVal = tuner.getChannel( tunerChannel );
if(retVal != null)
{
return retVal;
}
}
catch(Exception e)
{
//Fall through to logger below
}
}
mLog.info("Unable to source channel [" + config.getFrequency() + "] from preferred tuner [" +
config.getPreferredTuner() + "] - searching for another tuner");
}
while( it.hasNext() && retVal == null )
{
@@ -285,12 +332,10 @@ public class TunerModel extends AbstractTableModel implements Listener<TunerEven
}
catch ( SourceException e )
{
mLog.error( "error obtaining channel from tuner [" +
tuner.getName() + "]", e );
mLog.error( "error obtaining channel from tuner [" + tuner.getName() + "]", e );
}
}
return retVal;
}
}

View File

@@ -1,17 +1,17 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* Copyright (C) 2014-2018 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/>
******************************************************************************/
@@ -26,70 +26,164 @@ import io.github.dsheirer.source.tuner.frequency.FrequencyChangeEvent;
import io.github.dsheirer.source.tuner.frequency.IFrequencyChangeProcessor;
import net.miginfocom.swing.MigLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TunerSourceEditor extends Editor<Channel>
{
private static final long serialVersionUID = 1L;
private static final String NO_PREFERRED_TUNER = "(none)";
private static final String UNAVAILABLE_TUNER = " (unavailable)";
private JFrequencyControl mFrequencyControl;
private JComboBox<String> mTunerNameComboBox;
private TunerModel mTunerModel;
private List<String> mCurrentTunerNames;
public TunerSourceEditor()
{
init();
}
public TunerSourceEditor(TunerModel tunerModel)
{
mTunerModel = tunerModel;
init();
}
private void init()
{
setLayout( new MigLayout( "insets 0 0 0 0", "[left]", "" ) );
mFrequencyControl = new JFrequencyControl();
mFrequencyControl.setEnabled( false );
mFrequencyControl.addListener( new IFrequencyChangeProcessor()
{
@Override
public void frequencyChanged( FrequencyChangeEvent event )
{
setModified( true );
}
} );
add( mFrequencyControl );
}
private void init()
{
loadTunerNames();
public void save()
{
if( hasItem() && isModified() )
{
SourceConfigTuner config = new SourceConfigTuner();
config.setFrequency( mFrequencyControl.getFrequency() );
getItem().setSourceConfiguration( config );
}
setLayout(new MigLayout("insets 0 0 0 0", "[left]", ""));
mFrequencyControl = new JFrequencyControl();
mFrequencyControl.setEnabled(false);
mFrequencyControl.addListener(new IFrequencyChangeProcessor()
{
@Override
public void frequencyChanged(FrequencyChangeEvent event)
{
setModified(true);
}
});
add(mFrequencyControl);
setModified( false );
}
@Override
public void setItem( Channel item )
{
super.setItem( item );
if( hasItem() )
{
SourceConfiguration config = getItem().getSourceConfiguration();
mFrequencyControl.setEnabled( true );
mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]));
mTunerNameComboBox.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
setModified(true);
}
});
add(new JLabel("Preferred Tuner:"));
add(mTunerNameComboBox);
}
if( config instanceof SourceConfigTuner )
{
mFrequencyControl.setFrequency( ((SourceConfigTuner)config).getFrequency(), false );
setModified( false );
}
else
{
mFrequencyControl.setFrequency( 101000000, false );
setModified( true );
}
}
else
{
mFrequencyControl.setEnabled( false );
setModified( false );
}
}
private void loadTunerNames()
{
mCurrentTunerNames = new ArrayList<>();
for(Tuner tuner: mTunerModel.getTuners())
{
mCurrentTunerNames.add(tuner.getName());
}
Collections.sort(mCurrentTunerNames);
mCurrentTunerNames.add(0, NO_PREFERRED_TUNER);
}
private void updateTunerNameCombo(String preferredTuner)
{
if(preferredTuner != null && !mCurrentTunerNames.contains(preferredTuner))
{
List<String> updatedTunerNameList = new ArrayList<>(mCurrentTunerNames);
String unavailableTuner = preferredTuner + UNAVAILABLE_TUNER;
updatedTunerNameList.add(unavailableTuner);
String[] tunerNameArray = updatedTunerNameList.toArray(new String[updatedTunerNameList.size()]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
mTunerNameComboBox.setSelectedItem(unavailableTuner);
}
else
{
String[] tunerNameArray = mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
if(preferredTuner == null)
{
mTunerNameComboBox.setSelectedItem(NO_PREFERRED_TUNER);
}
else
{
mTunerNameComboBox.setSelectedItem(preferredTuner);
}
}
}
public void save()
{
if(hasItem() && isModified())
{
SourceConfigTuner config = new SourceConfigTuner();
config.setFrequency(mFrequencyControl.getFrequency());
String preferredTuner = (String)mTunerNameComboBox.getSelectedItem();
if(preferredTuner != null)
{
if(preferredTuner.equalsIgnoreCase(NO_PREFERRED_TUNER))
{
config.setPreferredTuner(null);
}
else if(preferredTuner.contains(UNAVAILABLE_TUNER))
{
//don't do anything - the config already contains this unavailable tuner name
}
else
{
config.setPreferredTuner(preferredTuner);
}
}
getItem().setSourceConfiguration(config);
}
setModified(false);
}
@Override
public void setItem(Channel item)
{
super.setItem(item);
if(hasItem())
{
SourceConfiguration config = getItem().getSourceConfiguration();
mFrequencyControl.setEnabled(true);
if(config instanceof SourceConfigTuner)
{
SourceConfigTuner tunerConfig = (SourceConfigTuner)config;
mFrequencyControl.setFrequency(tunerConfig.getFrequency(), false);
updateTunerNameCombo(tunerConfig.getPreferredTuner());
setModified(false);
}
else
{
mFrequencyControl.setFrequency(101000000, false);
setModified(true);
}
}
else
{
mFrequencyControl.setEnabled(false);
setModified(false);
}
}
}