/*******************************************************************************
* 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 instrument.gui;
import instrument.Instrumentable;
import instrument.InstrumentableProcessingChain;
import instrument.tap.Tap;
import instrument.tap.TapGroup;
import instrument.tap.TapViewPanel;
import instrument.tap.stream.BinaryTap;
import instrument.tap.stream.BinaryTapViewPanel;
import instrument.tap.stream.ComplexSampleTap;
import instrument.tap.stream.ComplexSampleTapViewPanel;
import instrument.tap.stream.ComplexTap;
import instrument.tap.stream.ComplexTapViewPanel;
import instrument.tap.stream.DibitTap;
import instrument.tap.stream.DibitTapViewPanel;
import instrument.tap.stream.EyeDiagramDataTap;
import instrument.tap.stream.EyeDiagramDataTapPanel;
import instrument.tap.stream.FloatTap;
import instrument.tap.stream.FloatTapViewPanel;
import instrument.tap.stream.QPSKTap;
import instrument.tap.stream.QPSKTapPanel;
import instrument.tap.stream.SymbolEventTap;
import instrument.tap.stream.SymbolEventTapViewPanel;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.List;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import message.Message;
import module.Module;
import module.decode.DecoderFactory;
import module.decode.config.AuxDecodeConfiguration;
import module.decode.config.DecodeConfiguration;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import record.config.RecordConfiguration;
import sample.Listener;
import source.IControllableFileSource;
import source.Source;
import alias.AliasList;
import controller.ResourceManager;
import controller.channel.Channel.ChannelType;
import controller.site.Site;
import controller.system.System;
public class DecoderViewFrame extends JInternalFrame
implements Listener
{
private static final long serialVersionUID = 1L;
private final static Logger mLog =
LoggerFactory.getLogger( DecoderViewFrame.class );
private DecodeConfiguration mDecodeConfig;
private InstrumentableProcessingChain mProcessingChain;
private IControllableFileSource mSource;
private HashMap mPanelMap =
new HashMap();
public DecoderViewFrame( ResourceManager resourceManager,
DecodeConfiguration decodeConfig,
RecordConfiguration recordConfig,
AuxDecodeConfiguration auxConfig,
AliasList aliasList,
IControllableFileSource source )
{
mSource = source;
mDecodeConfig = decodeConfig;
mProcessingChain = new InstrumentableProcessingChain( "instrumented" );
List modules = DecoderFactory
.getModules( ChannelType.STANDARD,
resourceManager,
decodeConfig,
recordConfig,
auxConfig,
aliasList,
new System( "Instrumented" ),
new Site( "Instrumented" ),
"Channel Name" );
mProcessingChain.addModules( modules );
mProcessingChain.addMessageListener( this );
mProcessingChain.setSource( (Source)mSource );
mProcessingChain.start();
initGui();
}
private void initGui()
{
setLayout( new MigLayout( "insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]" ) );
setTitle( "Decoder [" + mDecodeConfig.getDecoderType().getDisplayString() + "]" );
setPreferredSize( new Dimension( 450, 250 ) );
setSize( 450, 250 );
setResizable( true );
setClosable( true );
setIconifiable( true );
setMaximizable( false );
addMouseListener( new MouseListener()
{
@Override
public void mouseClicked( MouseEvent me )
{
if( me.getButton() == MouseEvent.BUTTON3 )
{
JPopupMenu popup = new JPopupMenu();
popup.add( getTapContextMenu() );
if( !mPanelMap.values().isEmpty() )
{
popup.add( new JSeparator() );
for( TapViewPanel panel: mPanelMap.values() )
{
popup.add( panel.getContextMenu() );
}
}
popup.show( DecoderViewFrame.this, me.getX(), me.getY() );
}
}
@Override
public void mouseEntered( MouseEvent arg0 ) {}
@Override
public void mouseExited( MouseEvent arg0 ) {}
@Override
public void mousePressed( MouseEvent arg0 ) {}
@Override
public void mouseReleased( MouseEvent arg0 ) {}
} );
}
private JMenu getTapContextMenu()
{
JMenu menu = new JMenu( "Modules" );
if( mProcessingChain != null )
{
for( Module module: mProcessingChain.getModules() )
{
if( module instanceof Instrumentable )
{
List groups = ((Instrumentable)module).getTapGroups();
for( TapGroup group: groups )
{
menu.add( new TapGroupMenu( group ) );
}
}
}
}
return menu;
}
public void add( Tap tap )
{
TapViewPanel panel = null;
switch( tap.getType() )
{
case EVENT_SYNC_DETECT:
break;
case STREAM_BINARY:
panel = new BinaryTapViewPanel( (BinaryTap)tap );
break;
case STREAM_COMPLEX:
panel = new ComplexTapViewPanel( (ComplexTap)tap );
break;
case STREAM_COMPLEX_SAMPLE:
panel = new ComplexSampleTapViewPanel( (ComplexSampleTap)tap );
break;
case STREAM_DIBIT:
panel = new DibitTapViewPanel( (DibitTap)tap );
break;
case STREAM_EYE_DIAGRAM:
panel = new EyeDiagramDataTapPanel( (EyeDiagramDataTap)tap ) ;
break;
case STREAM_FLOAT:
panel = new FloatTapViewPanel( (FloatTap)tap );
break;
case STREAM_QPSK:
panel = new QPSKTapPanel( (QPSKTap)tap );
break;
case STREAM_SYMBOL:
panel = new SymbolEventTapViewPanel( (SymbolEventTap)tap );
break;
}
if( panel != null )
{
add( panel, "span" );
validate();
mPanelMap.put( tap, panel );
for( Module module: mProcessingChain.getModules() )
{
if( module instanceof Instrumentable )
{
((Instrumentable)module).registerTap( tap );
}
}
}
else
{
mLog.info( "Tap panel is null, couldn't add for tap " +
tap.getName() + "[" + tap.getType().toString() + "]" );
}
}
public void remove( Tap tap )
{
for( Module module: mProcessingChain.getModules() )
{
if( module instanceof Instrumentable )
{
((Instrumentable)module).unregisterTap( tap );
}
}
TapViewPanel panel = mPanelMap.get( tap );
remove( panel );
validate();
mPanelMap.remove( tap );
}
public class AddAllTapsItem extends JMenuItem
{
private static final long serialVersionUID = 1L;
private final List mTaps;
public AddAllTapsItem( final List taps )
{
super( "All Taps" );
mTaps = taps;
addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
for( Tap tap: mTaps )
{
DecoderViewFrame.this.add( tap );
}
}
} );
}
}
public class TapSelectionItem extends JCheckBoxMenuItem
{
private static final long serialVersionUID = 1L;
private Tap mTap;
public TapSelectionItem( Tap tap )
{
super( tap.getName() );
mTap = tap;
if( mPanelMap.keySet().contains( tap ) )
{
setSelected( true );
}
addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent arg0 )
{
if( mPanelMap.keySet().contains( mTap ) )
{
DecoderViewFrame.this.remove( mTap );
}
else
{
DecoderViewFrame.this.add( mTap );
}
}
} );
}
}
@Override
public void receive( Message message )
{
mLog.info( message.toString() );
}
public class TapGroupMenu extends JMenu
{
private static final long serialVersionUID = 1L;
private TapGroup mTapGroup;
public TapGroupMenu( TapGroup tapGroup )
{
super( tapGroup.getName() );
mTapGroup = tapGroup;
add( new AddAllTapsItem( mTapGroup.getTaps() ) );
add( new JSeparator() );
for( Tap tap: mTapGroup.getTaps() )
{
add( new TapSelectionItem( tap ) );
}
}
}
}