mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 09:07:27 -05:00
Adds AliasModel and AliasEvent and support for conversion from legacy
playlist format. Renames PlaylistEditor to ChannelController
This commit is contained in:
@@ -24,12 +24,14 @@ import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.AliasDirectory;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.map.ChannelMapList;
|
||||
import controller.system.SystemList;
|
||||
|
||||
@XmlSeeAlso( { AliasDirectory.class,
|
||||
Alias.class,
|
||||
Channel.class,
|
||||
ChannelMapList.class,
|
||||
SystemList.class } )
|
||||
@@ -40,12 +42,24 @@ public class Playlist
|
||||
private AliasDirectory mAliasDirectory = new AliasDirectory();
|
||||
private ChannelMapList mChannelMapList = new ChannelMapList();
|
||||
private SystemList mSystemList = new SystemList();
|
||||
private List<Alias> mAliases = new ArrayList<>();
|
||||
private List<Channel> mChannels = new ArrayList<>();
|
||||
|
||||
public Playlist()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlElement( name = "alias" )
|
||||
public List<Alias> getAliases()
|
||||
{
|
||||
return mAliases;
|
||||
}
|
||||
|
||||
public void setAliases( List<Alias> aliases )
|
||||
{
|
||||
mAliases = aliases;
|
||||
}
|
||||
|
||||
@XmlElement( name = "channel" )
|
||||
public List<Channel> getChannels()
|
||||
{
|
||||
@@ -70,6 +84,13 @@ public class Playlist
|
||||
mAliasDirectory = directory;
|
||||
}
|
||||
|
||||
public boolean hasAliasDirectory()
|
||||
{
|
||||
return mAliasDirectory != null &&
|
||||
mAliasDirectory.getAliasList() != null &&
|
||||
!mAliasDirectory.getAliasList().isEmpty();
|
||||
}
|
||||
|
||||
@XmlElement( name = "system_list" )
|
||||
public SystemList getSystemList()
|
||||
{
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
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;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.coderazzi.filters.gui.AutoChoices;
|
||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import source.SourceManager;
|
||||
|
||||
import com.jidesoft.swing.JideSplitPane;
|
||||
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.ChannelEditor;
|
||||
import controller.channel.ChannelModel;
|
||||
|
||||
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,
|
||||
SourceManager sourceManager )
|
||||
{
|
||||
mChannelModel = channelModel;
|
||||
|
||||
mEditor = new ChannelEditor( channelModel, playlistManager, sourceManager );
|
||||
mChannelModel.addListener( mEditor );
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "insets 0 0 0 0",
|
||||
"[grow,fill]",
|
||||
"[grow,fill]") );
|
||||
|
||||
//System Configuration View and Editor
|
||||
mChannelTable = new JTable( mChannelModel );
|
||||
mChannelTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
|
||||
mChannelTable.getSelectionModel().addListSelectionListener( this );
|
||||
mChannelTable.setAutoCreateRowSorter( 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( listAndButtonsPanel );
|
||||
splitPane.add( mEditor );
|
||||
|
||||
add( splitPane );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged( ListSelectionEvent event )
|
||||
{
|
||||
//This limits event firing to only when selection is complete
|
||||
if( !event.getValueIsAdjusting() )
|
||||
{
|
||||
int selectedRow = mChannelTable.getSelectedRow();
|
||||
|
||||
if( selectedRow != -1 )
|
||||
{
|
||||
int index = mChannelTable.convertRowIndexToModel( mChannelTable.getSelectedRow() );
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,10 +37,11 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import properties.SystemProperties;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.ChannelModel;
|
||||
import controller.site.Site;
|
||||
import controller.system.SystemList;
|
||||
import alias.Alias;
|
||||
import alias.AliasDirectory;
|
||||
import alias.AliasList;
|
||||
import alias.AliasModel;
|
||||
import alias.Group;
|
||||
import controller.ThreadPoolManager;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
@@ -57,10 +58,8 @@ public class PlaylistManager implements ChannelEventListener
|
||||
|
||||
private Playlist mPlaylist = new Playlist();
|
||||
|
||||
private ChannelModel mChannelModel;
|
||||
|
||||
public PlaylistManager( ChannelModel channelModel )
|
||||
private ThreadPoolManager mThreadPoolManager;
|
||||
private AliasModel mAliasModel;
|
||||
private ChannelModel mChannelModel;
|
||||
|
||||
private AtomicBoolean mPlaylistSavePending = new AtomicBoolean();
|
||||
@@ -76,10 +75,12 @@ public class PlaylistManager implements ChannelEventListener
|
||||
* @param threadPoolManager
|
||||
* @param channelModel
|
||||
*/
|
||||
public PlaylistManager( ThreadPoolManager threadPoolManager,
|
||||
public PlaylistManager( ThreadPoolManager threadPoolManager,
|
||||
AliasModel aliasModel,
|
||||
ChannelModel channelModel )
|
||||
{
|
||||
mThreadPoolManager = threadPoolManager;
|
||||
mAliasModel = aliasModel;
|
||||
mChannelModel = channelModel;
|
||||
|
||||
//Register for channel events so that we can save the playlist when
|
||||
@@ -101,7 +102,8 @@ public class PlaylistManager implements ChannelEventListener
|
||||
//all of the data
|
||||
|
||||
mPlaylistLoading = true;
|
||||
|
||||
|
||||
mAliasModel.addAliases( mPlaylist.getAliases() );
|
||||
mChannelModel.addChannels( mPlaylist.getChannels() );
|
||||
|
||||
mPlaylistLoading = false;
|
||||
@@ -168,11 +170,57 @@ public class PlaylistManager implements ChannelEventListener
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel event listener method. Monitors channel events for events that
|
||||
* indicate that the playlist has changed and queues automatic playlist
|
||||
* saving.
|
||||
*/
|
||||
@Override
|
||||
public void channelChanged( ChannelEvent event )
|
||||
{
|
||||
//Only save playlist for changes to standard channels (not traffic)
|
||||
if( event.getChannel().getChannelType() == ChannelType.STANDARD )
|
||||
{
|
||||
switch( event.getEvent() )
|
||||
{
|
||||
case NOTIFICATION_ADD:
|
||||
case NOTIFICATION_CONFIGURATION_CHANGE:
|
||||
case NOTIFICATION_DELETE:
|
||||
case NOTIFICATION_PROCESSING_START:
|
||||
case NOTIFICATION_PROCESSING_STOP:
|
||||
schedulePlaylistSave();
|
||||
break;
|
||||
case NOTIFICATION_ENABLE_REJECTED:
|
||||
case NOTIFICATION_SELECTION_CHANGE:
|
||||
case NOTIFICATION_STATE_RESET:
|
||||
case REQUEST_DELETE:
|
||||
case REQUEST_DESELECT:
|
||||
case REQUEST_DISABLE:
|
||||
case REQUEST_ENABLE:
|
||||
case REQUEST_SELECT:
|
||||
//Do nothing for these event types
|
||||
break;
|
||||
default:
|
||||
//When a new event enum entry is added and received, throw an
|
||||
//exception here to ensure developer adds support for the
|
||||
//use case
|
||||
throw new IllegalArgumentException( "Unrecognized Channel "
|
||||
+ "Event [" + event.getEvent().name() + "]" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
//TODO: recreate the playlist and load values from each of the models
|
||||
|
||||
mLog.debug( "Aliases in model:" + mAliasModel.getAliases().size() );
|
||||
mPlaylist.setAliases( mAliasModel.getAliases() );
|
||||
mLog.debug( "Aliases in playlist:" + mPlaylist.getAliases().size() );
|
||||
|
||||
mLog.debug( "Channels in model:" + mChannelModel.getChannels().size() );
|
||||
mPlaylist.setChannels( mChannelModel.getChannels() );
|
||||
mLog.debug( "Channels in playlist:" + mPlaylist.getChannels().size() );
|
||||
|
||||
JAXBContext context = null;
|
||||
|
||||
@@ -370,16 +418,27 @@ public class PlaylistManager implements ChannelEventListener
|
||||
playlistPath.toString() + "]" );
|
||||
}
|
||||
|
||||
boolean saveRequired = false;
|
||||
|
||||
if( mPlaylist == null )
|
||||
{
|
||||
mPlaylist = new Playlist();
|
||||
save();
|
||||
saveRequired = true;
|
||||
}
|
||||
|
||||
|
||||
//Check for and convert from legacy play list format
|
||||
if( mPlaylist.hasSystemList() )
|
||||
if( mPlaylist.hasSystemList() || mPlaylist.hasAliasDirectory() )
|
||||
{
|
||||
convertPlaylistFormat();
|
||||
saveRequired = true;
|
||||
}
|
||||
|
||||
transferPlaylistToModels();
|
||||
|
||||
if( saveRequired )
|
||||
{
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,35 +447,60 @@ public class PlaylistManager implements ChannelEventListener
|
||||
*/
|
||||
private void convertPlaylistFormat()
|
||||
{
|
||||
mLog.info( "Legacy playlist format detected - converting ..." );
|
||||
mLog.info( "Legacy playlist format detected - converting" );
|
||||
|
||||
createBackupPlaylist();
|
||||
|
||||
//Playlist version 1 to version 2 format conversion. In order to keep
|
||||
//backwards compatibility, transfer all of the System-Site-Channel
|
||||
//objects over to the new channel list format
|
||||
SystemList systemList = mPlaylist.getSystemList();
|
||||
|
||||
for( controller.system.System system: systemList.getSystem() )
|
||||
if( mPlaylist.hasSystemList() )
|
||||
{
|
||||
for( Site site: system.getSite() )
|
||||
SystemList systemList = mPlaylist.getSystemList();
|
||||
|
||||
for( controller.system.System system: systemList.getSystem() )
|
||||
{
|
||||
for( Channel channel: site.getChannel() )
|
||||
for( Site site: system.getSite() )
|
||||
{
|
||||
channel.setSystem( system.getName() );
|
||||
channel.setSite( site.getName() );
|
||||
|
||||
mPlaylist.getChannels().add( channel );
|
||||
for( Channel channel: site.getChannel() )
|
||||
{
|
||||
channel.setSystem( system.getName() );
|
||||
channel.setSite( site.getName() );
|
||||
|
||||
mPlaylist.getChannels().add( channel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPlaylist.getSystemList().clearSystems();
|
||||
|
||||
mLog.info( "Converted [" + mPlaylist.getChannels().size() +
|
||||
"] channels to new playlist format" );
|
||||
}
|
||||
|
||||
if( mPlaylist.hasAliasDirectory() )
|
||||
{
|
||||
AliasDirectory aliasDirectory = mPlaylist.getAliasDirectory();
|
||||
|
||||
for( AliasList list: aliasDirectory.getAliasList() )
|
||||
{
|
||||
for( Group group: list.getGroup() )
|
||||
{
|
||||
for( Alias alias: group.getAlias() )
|
||||
{
|
||||
alias.setList( list.getName() );
|
||||
alias.setGroup( group.getName() );
|
||||
|
||||
mPlaylist.getAliases().add( alias );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPlaylist.getAliasDirectory().clearAliasLists();
|
||||
|
||||
mLog.info( "Converted [" + mPlaylist.getAliases().size() +
|
||||
"] aliases to new playlist format" );
|
||||
}
|
||||
|
||||
mPlaylist.getSystemList().clearSystems();
|
||||
|
||||
mLog.info( "Converted [" + mPlaylist.getChannels().size() +
|
||||
"] channels to new playlist format" );
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -448,46 +532,5 @@ public class PlaylistManager implements ChannelEventListener
|
||||
|
||||
mPlaylistSavePending.set( false );
|
||||
}
|
||||
|
||||
//Check for and convert from legacy play list format
|
||||
if( mPlaylist.hasSystemList() )
|
||||
{
|
||||
convertPlaylistFormat();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts playlist data over to new format
|
||||
*/
|
||||
private void convertPlaylistFormat()
|
||||
{
|
||||
mLog.info( "Legacy playlist format detected - converting ..." );
|
||||
|
||||
createBackupPlaylist();
|
||||
|
||||
//Playlist version 1 to version 2 format conversion. In order to keep
|
||||
//backwards compatibility, transfer all of the System-Site-Channel
|
||||
//objects over to the new channel list format
|
||||
SystemList systemList = mPlaylist.getSystemList();
|
||||
|
||||
for( controller.system.System system: systemList.getSystem() )
|
||||
{
|
||||
for( Site site: system.getSite() )
|
||||
{
|
||||
for( Channel channel: site.getChannel() )
|
||||
{
|
||||
channel.setSystem( system.getName() );
|
||||
channel.setSite( site.getName() );
|
||||
|
||||
mPlaylist.getChannels().add( channel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPlaylist.getSystemList().clearSystems();
|
||||
|
||||
mLog.info( "Converted [" + mPlaylist.getChannels().size() + "] channels to new playlist format" );
|
||||
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user