Updates playlist editor with Add, Copy/Clone and Delete channel

functionality
This commit is contained in:
denny
2016-01-24 10:31:31 -05:00
parent 61f68c08e8
commit da924e8b3a
7 changed files with 337 additions and 68 deletions

View File

@@ -23,14 +23,17 @@ import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import module.decode.DecoderType;
import module.decode.config.AuxDecodeConfiguration;
import module.decode.config.DecodeConfigFactory;
import module.decode.config.DecodeConfiguration;
import module.log.EventLogType;
import module.log.config.EventLogConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import record.RecorderType;
import record.config.RecordConfiguration;
import source.SourceType;
import source.config.SourceConfigFactory;
@@ -115,6 +118,50 @@ public class Channel extends Configuration implements IFrequencyChangeProcessor
{
mChannelID = UNIQUE_ID++;
}
/**
* Creates a (new) deep copy of this channel
*/
public Channel copyOf()
{
Channel channel = new Channel( mName );
channel.setSystem( mSystem );
channel.setSite( mSite );
channel.setAliasListName( mAliasListName );
AuxDecodeConfiguration aux = new AuxDecodeConfiguration();
for( DecoderType auxType: aux.getAuxDecoders() )
{
aux.addAuxDecoder( auxType );
}
channel.setAuxDecodeConfiguration( aux );
channel.setDecodeConfiguration( DecodeConfigFactory.copy( mDecodeConfiguration ) );
EventLogConfiguration log = new EventLogConfiguration();
for( EventLogType logType: mEventLogConfiguration.getLoggers() )
{
log.addLogger( logType );
}
channel.setEventLogConfiguration( log );
RecordConfiguration record = new RecordConfiguration();
for( RecorderType recordType: mRecordConfiguration.getRecorders() )
{
record.addRecorder( recordType );
}
channel.setRecordConfiguration( record );
channel.setSourceConfiguration( SourceConfigFactory.copy( mSourceConfiguration ) );
return channel;
}
//TODO: remove this
/**

View File

@@ -17,21 +17,16 @@
******************************************************************************/
package controller.channel;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.JTextField;
import module.decode.AuxDecodeComponentEditor;
import module.decode.DecodeComponentEditor;
@@ -45,7 +40,6 @@ import playlist.PlaylistManager;
import record.RecordComponentEditor;
import source.SourceComponentEditor;
import source.SourceManager;
import alias.AliasList;
import com.jidesoft.swing.JideTabbedPane;
@@ -169,7 +163,6 @@ public class ChannelEditor extends JPanel
@Override
public void channelChanged( ChannelEvent event )
{
mLog.debug( "Received channel event: " + event.getEvent() );
if( mChannel != null && mChannel == event.getChannel() )
{
switch( event.getEvent() )
@@ -302,36 +295,6 @@ public class ChannelEditor extends JPanel
mChannelModel.broadcast( new ChannelEvent( mChannel,
Event.NOTIFICATION_CONFIGURATION_CHANGE ) );
}
// @Override
// public void reset()
// {
// mChannelName.setText( mChannel.getName() );
// mChannelName.requestFocus();
// mChannelName.requestFocusInWindow();
//
// mChannelEnabled.setSelected( mChannel.getEnabled() );
// mChannelEnabled.requestFocus();
// mChannelEnabled.requestFocusInWindow();
//
// String aliasListName = mChannel.getAliasListName();
//
// if( aliasListName != null )
// {
// AliasList selected = mPlaylistManager.getPlayist().getAliasDirectory()
// .getAliasList( aliasListName );
//
// mComboAliasLists.setSelectedItem( selected );
// }
//
//
// mSourceEditor.reset();
// mDecodeEditor.reset();
// mAuxDecodeEditor.reset();
// mEventLogEditor.reset();
// mRecordEditor.reset();
// }
// /**
// * Validate the specified editor against each of the component editors
// */

View File

@@ -26,6 +26,10 @@ import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import playlist.PlaylistEditor;
import module.decode.DecoderType;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelEvent.Event;
@@ -35,6 +39,8 @@ import controller.channel.ChannelEvent.Event;
*/
public class ChannelModel implements IChannelEventBroadcaster, TableModel
{
private final static Logger mLog = LoggerFactory.getLogger( ChannelModel.class );
private ChannelSelectionManager mChannelSelectionManager;
private List<Channel> mChannels = new ArrayList<>();
private List<Channel> mTrafficChannels = new ArrayList<>();
@@ -55,6 +61,16 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
return Collections.unmodifiableList( mChannels );
}
public Channel getChannelAtIndex( int row )
{
if( mChannels.size() >= row )
{
return mChannels.get( row );
}
return null;
}
/**
* Returns a list of unique system values from across the channel set
*/
@@ -150,20 +166,23 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
/**
* Adds the channel to the model and broadcasts a channel add event
*/
public void addChannel( Channel channel )
public int addChannel( Channel channel )
{
int index = -1;
switch( channel.getChannelType() )
{
case STANDARD:
mChannels.add( channel );
int index = mChannels.size() - 1;
index = mChannels.size() - 1;
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT ) );
break;
case TRAFFIC:
mTrafficChannels.add( channel );
index = mChannels.size() - 1;
break;
default:
break;
@@ -175,6 +194,8 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
{
broadcast( new ChannelEvent( channel, Event.REQUEST_ENABLE ) );
}
return index;
}
/**
@@ -182,27 +203,30 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
*/
public void removeChannel( Channel channel )
{
switch( channel.getChannelType() )
if( channel != null )
{
case STANDARD:
int index = mChannels.indexOf( channel );
mChannels.remove( channel );
switch( channel.getChannelType() )
{
case STANDARD:
int index = mChannels.indexOf( channel );
mChannels.remove( channel );
if( index >= 0 )
{
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE ) );
}
break;
case TRAFFIC:
mTrafficChannels.remove( channel );
break;
default:
break;
if( index >= 0 )
{
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE ) );
}
break;
case TRAFFIC:
mTrafficChannels.remove( channel );
break;
default:
break;
}
broadcast( new ChannelEvent( channel, Event.NOTIFICATION_DELETE ) );
}
broadcast( new ChannelEvent( channel, Event.NOTIFICATION_DELETE ) );
}
/**

View File

@@ -43,18 +43,18 @@ public class DecodeConfigFactory
case AM:
retVal = new DecodeConfigAM();
break;
case NBFM:
retVal = new DecodeConfigNBFM();
case LTR_NET:
retVal = new DecodeConfigLTRNet();
break;
case LTR_STANDARD:
retVal = new DecodeConfigLTRStandard();
break;
case LTR_NET:
retVal = new DecodeConfigLTRNet();
break;
case MPT1327:
retVal = new DecodeConfigMPT1327();
break;
case NBFM:
retVal = new DecodeConfigNBFM();
break;
case PASSPORT:
retVal = new DecodeConfigPassport();
break;
@@ -68,4 +68,73 @@ public class DecodeConfigFactory
return retVal;
}
/**
* Creates a copy of the configuration
*/
public static DecodeConfiguration copy( DecodeConfiguration config )
{
if( config != null )
{
switch( config.getDecoderType() )
{
case AM:
DecodeConfigAM originalAM = (DecodeConfigAM)config;
DecodeConfigAM copyAM = new DecodeConfigAM();
copyAM.setAFC( originalAM.getAFC() );
copyAM.setAFCMaximumCorrection( originalAM.getAFCMaximumCorrection() );
return copyAM;
case LTR_NET:
DecodeConfigLTRNet originalLTRNet = (DecodeConfigLTRNet)config;
DecodeConfigLTRNet copyLTRNet = new DecodeConfigLTRNet();
copyLTRNet.setAFC( originalLTRNet.getAFC() );
copyLTRNet.setAFCMaximumCorrection( originalLTRNet.getAFCMaximumCorrection() );
copyLTRNet.setMessageDirection( originalLTRNet.getMessageDirection() );
return copyLTRNet;
case LTR_STANDARD:
DecodeConfigLTRStandard originalLTRStandard = (DecodeConfigLTRStandard)config;
DecodeConfigLTRStandard copyLTRStandard = new DecodeConfigLTRStandard();
copyLTRStandard.setAFC( originalLTRStandard.getAFC() );
copyLTRStandard.setAFCMaximumCorrection( originalLTRStandard.getAFCMaximumCorrection() );
copyLTRStandard.setMessageDirection( originalLTRStandard.getMessageDirection() );
return copyLTRStandard;
case MPT1327:
DecodeConfigMPT1327 originalMPT = (DecodeConfigMPT1327)config;
DecodeConfigMPT1327 copyMPT = new DecodeConfigMPT1327();
copyMPT.setAFC( originalMPT.getAFC() );
copyMPT.setAFCMaximumCorrection( originalMPT.getAFCMaximumCorrection() );
copyMPT.setCallTimeout( originalMPT.getCallTimeout() );
copyMPT.setChannelMapName( originalMPT.getChannelMapName() );
copyMPT.setSync( originalMPT.getSync() );
copyMPT.setTrafficChannelPoolSize( originalMPT.getTrafficChannelPoolSize() );
return copyMPT;
case NBFM:
DecodeConfigNBFM originalNBFM = (DecodeConfigNBFM)config;
DecodeConfigNBFM copyNBFM = new DecodeConfigNBFM();
copyNBFM.setAFC( originalNBFM.getAFC() );
copyNBFM.setAFCMaximumCorrection( originalNBFM.getAFCMaximumCorrection() );
return copyNBFM;
case P25_PHASE1:
DecodeConfigP25Phase1 originalP25 = (DecodeConfigP25Phase1)config;
DecodeConfigP25Phase1 copyP25 = new DecodeConfigP25Phase1();
copyP25.setAFC( originalP25.getAFC() );
copyP25.setAFCMaximumCorrection( originalP25.getAFCMaximumCorrection() );
copyP25.setIgnoreDataCalls( originalP25.getIgnoreDataCalls() );
copyP25.setModulation( originalP25.getModulation() );
copyP25.setTrafficChannelPoolSize( originalP25.getTrafficChannelPoolSize() );
return copyP25;
case PASSPORT:
DecodeConfigPassport originalPass = (DecodeConfigPassport)config;
DecodeConfigPassport copyPass = new DecodeConfigPassport();
copyPass.setAFC( originalPass.getAFC() );
copyPass.setAFCMaximumCorrection( originalPass.getAFCMaximumCorrection() );
return copyPass;
default:
throw new IllegalArgumentException( "Unrecognized decoder "
+ "configuration type:" + config.getDecoderType() );
}
}
return null;
}
}

View File

@@ -1,5 +1,11 @@
package playlist;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
@@ -22,14 +28,24 @@ import controller.channel.Channel;
import controller.channel.ChannelEditor;
import controller.channel.ChannelModel;
public class PlaylistEditor extends JPanel implements ListSelectionListener
public class PlaylistEditor extends JPanel
implements ActionListener, ListSelectionListener
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( PlaylistEditor.class );
private ChannelModel mChannelModel;
private JTable mChannelTable;
private TableFilterHeader mTableFilterHeader;
private ChannelEditor mEditor;
private static final String NEW_CHANNEL = "New";
private static final String COPY_CHANNEL = "Copy";
private static final String DELETE_CHANNEL = "Delete";
private JButton mNewChannelButton = new JButton( NEW_CHANNEL );
private JButton mCopyChannelButton = new JButton( COPY_CHANNEL );
private JButton mDeleteChannelButton = new JButton( DELETE_CHANNEL );
public PlaylistEditor( ChannelModel channelModel,
PlaylistManager playlistManager,
@@ -55,16 +71,42 @@ public class PlaylistEditor extends JPanel implements ListSelectionListener
mChannelTable.getSelectionModel().addListSelectionListener( this );
mChannelTable.setAutoCreateRowSorter( true );
TableFilterHeader channelHeaderFilter =
new TableFilterHeader( mChannelTable, AutoChoices.ENABLED );
channelHeaderFilter.setFilterOnUpdates( true );
mTableFilterHeader = new TableFilterHeader( mChannelTable, AutoChoices.ENABLED );
mTableFilterHeader.setFilterOnUpdates( true );
JScrollPane channelScroller = new JScrollPane( mChannelTable );
JPanel buttonsPanel = new JPanel();
buttonsPanel.setLayout(
new MigLayout( "insets 0 0 0 0", "[grow,fill][grow,fill][grow,fill]", "[]") );
mNewChannelButton.addActionListener( this );
mNewChannelButton.setToolTipText( "Adds a new default channel" );
buttonsPanel.add( mNewChannelButton );
mCopyChannelButton.addActionListener( this );
mCopyChannelButton.setEnabled( false );
mCopyChannelButton.setToolTipText( "Creates a copy of the currently selected channel and adds it" );
buttonsPanel.add( mCopyChannelButton );
mDeleteChannelButton.addActionListener( this );
mDeleteChannelButton.setEnabled( false );
mDeleteChannelButton.setToolTipText( "Deletes the currently selected channel" );
buttonsPanel.add( mDeleteChannelButton );
JPanel listAndButtonsPanel = new JPanel();
listAndButtonsPanel.setLayout(
new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill][]") );
listAndButtonsPanel.add( channelScroller, "wrap" );
listAndButtonsPanel.add( buttonsPanel );
JideSplitPane splitPane = new JideSplitPane( JideSplitPane.HORIZONTAL_SPLIT );
splitPane.setDividerSize( 5 );
splitPane.setShowGripper( true );
splitPane.add( channelScroller );
splitPane.add( listAndButtonsPanel );
splitPane.add( mEditor );
add( splitPane );
@@ -82,17 +124,99 @@ public class PlaylistEditor extends JPanel implements ListSelectionListener
{
int index = mChannelTable.convertRowIndexToModel( mChannelTable.getSelectedRow() );
Channel channel = mChannelModel.getChannels().get( index );
Channel channel = mChannelModel.getChannelAtIndex( index );
if( channel != null )
{
mEditor.setChannel( channel );
mCopyChannelButton.setEnabled( true );
mDeleteChannelButton.setEnabled( true );
}
}
else
{
mEditor.setChannel( null );
mCopyChannelButton.setEnabled( false );
mDeleteChannelButton.setEnabled( false );
}
}
}
/**
* Selects the channel's table row and scrolls the table's viewport to show it
*/
private void addChannel( Channel channel )
{
//HACK: when inserting a row to the model, the JTable gets
//notified and attempts to tell the coderazzi table filter
//adaptive choices filter to refresh before the table filter is
//notified of the row additions, causing an index out of bounds
//exception. We turn off adaptive choices temporarily, add the
//channel, and turn on adaptive choices again.
mTableFilterHeader.setAdaptiveChoices( false );
int index = mChannelModel.addChannel( channel );
mTableFilterHeader.setAdaptiveChoices( true );
if( index >= 0 )
{
int translatedIndex = mChannelTable.convertRowIndexToView( index );
mChannelTable.setRowSelectionInterval( translatedIndex, translatedIndex );
mChannelTable.scrollRectToVisible(
new Rectangle( mChannelTable.getCellRect( translatedIndex, 0, true ) ) );
}
}
private Channel getSelectedChannel()
{
int index = mChannelTable.getSelectedRow();
if( index >= 0 )
{
return mChannelModel.getChannelAtIndex(
mChannelTable.convertRowIndexToModel( index ) );
}
return null;
}
/**
* Responds to New, Copy and Delete Channel button invocations
*/
@Override
public void actionPerformed( ActionEvent event )
{
switch( event.getActionCommand() )
{
case NEW_CHANNEL:
addChannel( new Channel( "New Channel" ) );
break;
case COPY_CHANNEL:
Channel selected = getSelectedChannel();
if( selected != null )
{
addChannel( selected.copyOf() );
}
break;
case DELETE_CHANNEL:
Channel toDelete = getSelectedChannel();
if( toDelete != null )
{
int choice = JOptionPane.showConfirmDialog( PlaylistEditor.this,
"Do you want to delete this channel?", "Delete Channel?",
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE );
if( choice == JOptionPane.YES_OPTION )
{
mChannelModel.removeChannel( toDelete );
}
}
break;
default:
break;
}
}
}

View File

@@ -97,6 +97,9 @@ public class PlaylistManager implements ChannelEventListener
*/
private void transferPlaylistToModels()
{
//TODO: delete the playlist after we've loaded it, since the models will have
//all of the data
mPlaylistLoading = true;
mChannelModel.addChannels( mPlaylist.getChannels() );
@@ -167,6 +170,10 @@ public class PlaylistManager implements ChannelEventListener
public void save()
{
//TODO: recreate the playlist and load values from each of the models
mPlaylist.setChannels( mChannelModel.getChannels() );
JAXBContext context = null;
SystemProperties props = SystemProperties.getInstance();

View File

@@ -50,4 +50,39 @@ public class SourceConfigFactory
return retVal;
}
/**
* Creates a copy of the configuration
*/
public static SourceConfiguration copy( SourceConfiguration config )
{
if( config != null )
{
switch( config.getSourceType() )
{
case MIXER:
SourceConfigMixer originalMixer = (SourceConfigMixer)config;
SourceConfigMixer copyMixer = new SourceConfigMixer();
copyMixer.setChannel( originalMixer.getChannel() );
copyMixer.setMixer( originalMixer.getMixer() );
return copyMixer;
case RECORDING:
SourceConfigRecording originalRec = (SourceConfigRecording)config;
SourceConfigRecording copyRec = new SourceConfigRecording();
copyRec.setFrequency( originalRec.getFrequency() );
copyRec.setRecordingAlias( originalRec.getRecordingAlias() );
return copyRec;
case TUNER:
SourceConfigTuner originalTuner = (SourceConfigTuner)config;
SourceConfigTuner copyTuner = new SourceConfigTuner();
copyTuner.setFrequency( originalTuner.getFrequency() );
return copyTuner;
case NONE:
default:
return new SourceConfigNone();
}
}
return null;
}
}