mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 00:57:31 -05:00
Adds message filtering, message history clear, and message history size features to the 'Messages' tab. Filter window dynamically constructs a list of filters from the primary filter and each of the auxiliary filters enabled within the currently selected/enabled processing channel.
This commit is contained in:
35
src/filter/AllPassFilter.java
Normal file
35
src/filter/AllPassFilter.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package filter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implements a message filter that passes (true) all messages
|
||||
*/
|
||||
@SuppressWarnings( "rawtypes" )
|
||||
public class AllPassFilter<T> extends Filter<T>
|
||||
{
|
||||
public AllPassFilter()
|
||||
{
|
||||
super( "Allow All Messages" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passes( T t )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess( T t )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public List getFilterElements()
|
||||
{
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
}
|
||||
55
src/filter/Filter.java
Normal file
55
src/filter/Filter.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package filter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Filter<T> implements IFilter<T>
|
||||
{
|
||||
protected String mName;
|
||||
protected boolean mEnabled = true;
|
||||
|
||||
public Filter( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this filter is enabled or disabled
|
||||
*/
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables (true) or disables (false) this filter. An enabled filter will
|
||||
* evaluate messages and a disabled filter will return false on all message
|
||||
* test methods.
|
||||
*/
|
||||
public void setEnabled( boolean enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of filter elements managed by this filter
|
||||
*/
|
||||
public abstract List<FilterElement<?>> getFilterElements();
|
||||
|
||||
/**
|
||||
* Name of this filter
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void setName( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
400
src/filter/FilterEditorPanel.java
Normal file
400
src/filter/FilterEditorPanel.java
Normal file
@@ -0,0 +1,400 @@
|
||||
package filter;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.CellEditorListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreeCellEditor;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
public class FilterEditorPanel<T> extends JPanel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JTree mTree;
|
||||
private DefaultTreeModel mModel;
|
||||
private FilterSet<T> mFilterSet;
|
||||
|
||||
public FilterEditorPanel( FilterSet<T> filterSet )
|
||||
{
|
||||
setLayout( new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]") );
|
||||
|
||||
mFilterSet = filterSet;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode( mFilterSet );
|
||||
|
||||
mModel = new DefaultTreeModel( root );
|
||||
|
||||
addFilterSet( mFilterSet, root );
|
||||
|
||||
mTree = new JTree( mModel );
|
||||
mTree.setShowsRootHandles( true );
|
||||
|
||||
mTree.addMouseListener( new MouseHandler() );
|
||||
|
||||
mTree.getSelectionModel().setSelectionMode(
|
||||
TreeSelectionModel.SINGLE_TREE_SELECTION );
|
||||
|
||||
mTree.setCellRenderer( new EditorTreeCellRenderer() );
|
||||
|
||||
mTree.setCellEditor( new FilterTreeNodeEditor() );
|
||||
|
||||
mTree.setEditable( true );
|
||||
|
||||
add( mTree );
|
||||
}
|
||||
|
||||
private void addFilterSet( FilterSet<T> filterSet, DefaultMutableTreeNode parent )
|
||||
{
|
||||
List<IFilter<T>> filters = filterSet.getFilters();
|
||||
|
||||
/* sort the filters in alphabetical order by name */
|
||||
Collections.sort( filters, new Comparator<IFilter<?>>()
|
||||
{
|
||||
@Override
|
||||
public int compare( IFilter<?> first, IFilter<?> second )
|
||||
{
|
||||
return first.getName().compareTo( second.getName() );
|
||||
}
|
||||
});
|
||||
|
||||
for( IFilter<T> filter: filters )
|
||||
{
|
||||
DefaultMutableTreeNode child = new DefaultMutableTreeNode( filter );
|
||||
|
||||
mModel.insertNodeInto( child, parent, parent.getChildCount() );
|
||||
|
||||
if( filter instanceof FilterSet )
|
||||
{
|
||||
addFilterSet( (FilterSet<T>)filter, child );
|
||||
}
|
||||
else if( filter instanceof Filter )
|
||||
{
|
||||
addFilter( (Filter<T>)filter, child );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addFilter( Filter<T> filter, DefaultMutableTreeNode parent )
|
||||
{
|
||||
List<FilterElement<?>> elements = filter.getFilterElements();
|
||||
|
||||
Collections.sort( elements );
|
||||
|
||||
for( FilterElement<?> element: elements )
|
||||
{
|
||||
DefaultMutableTreeNode child = new DefaultMutableTreeNode( element );
|
||||
|
||||
mModel.insertNodeInto( child, parent, parent.getChildCount() );
|
||||
}
|
||||
}
|
||||
|
||||
public class MouseHandler implements MouseListener
|
||||
{
|
||||
public MouseHandler()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent event )
|
||||
{
|
||||
if( SwingUtilities.isRightMouseButton( event ) )
|
||||
{
|
||||
int row = mTree.getRowForLocation( event.getX(),
|
||||
event.getY() );
|
||||
|
||||
if( row != -1 )
|
||||
{
|
||||
mTree.setSelectionRow( row );
|
||||
|
||||
Object selectedNode =
|
||||
mTree.getLastSelectedPathComponent();
|
||||
|
||||
if( selectedNode instanceof DefaultMutableTreeNode )
|
||||
{
|
||||
final DefaultMutableTreeNode node =
|
||||
(DefaultMutableTreeNode)selectedNode;
|
||||
|
||||
if( node.getChildCount() > 0 )
|
||||
{
|
||||
JPopupMenu selectionMenu = new JPopupMenu();
|
||||
|
||||
JMenuItem selectAll = new JMenuItem( "Select All" );
|
||||
selectAll.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
{
|
||||
setFilterEnabled( mModel, node, true );
|
||||
}
|
||||
});
|
||||
|
||||
selectionMenu.add( selectAll );
|
||||
|
||||
JMenuItem deselectAll = new JMenuItem( "Deselect All" );
|
||||
deselectAll.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
{
|
||||
setFilterEnabled( mModel, node, false );
|
||||
}
|
||||
});
|
||||
|
||||
selectionMenu.add( deselectAll );
|
||||
|
||||
selectionMenu.show( mTree,
|
||||
event.getX(),
|
||||
event.getY() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ){}
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ){}
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent e ){}
|
||||
@Override
|
||||
public void mouseExited( MouseEvent e ){}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively sets the enabled state on all filter node children below the
|
||||
* specified parent node.
|
||||
*
|
||||
* @param model - model containing the tree nodes
|
||||
* @param node - parent node
|
||||
* @param enabled - true or false to enable or disable the filters
|
||||
*/
|
||||
private void setFilterEnabled( DefaultTreeModel model,
|
||||
DefaultMutableTreeNode node,
|
||||
boolean enabled )
|
||||
{
|
||||
Object obj = node.getUserObject();
|
||||
|
||||
if( obj instanceof FilterSet<?> )
|
||||
{
|
||||
((FilterSet<?>)obj).setEnabled( enabled );
|
||||
}
|
||||
else if( obj instanceof Filter )
|
||||
{
|
||||
((Filter<?>)obj).setEnabled( enabled );
|
||||
}
|
||||
else if( obj instanceof FilterElement )
|
||||
{
|
||||
((FilterElement<?>)obj).setEnabled( enabled );
|
||||
}
|
||||
|
||||
model.nodeChanged( node );
|
||||
|
||||
/* Recursively set the children of this node */
|
||||
Enumeration<?> children = node.children();
|
||||
|
||||
while( children.hasMoreElements() )
|
||||
{
|
||||
Object child = children.nextElement();
|
||||
|
||||
if( child instanceof DefaultMutableTreeNode )
|
||||
{
|
||||
setFilterEnabled( model, (DefaultMutableTreeNode)child, enabled );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EditorTreeCellRenderer extends DefaultTreeCellRenderer
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Component getTreeCellRendererComponent( JTree tree,
|
||||
Object treeNode,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus )
|
||||
{
|
||||
if( treeNode instanceof DefaultMutableTreeNode )
|
||||
{
|
||||
Object userObject = ((DefaultMutableTreeNode)treeNode).getUserObject();
|
||||
|
||||
JCheckBox checkBox = null;
|
||||
|
||||
if( userObject instanceof IFilter )
|
||||
{
|
||||
IFilter<?> filter = (IFilter<?>)userObject;
|
||||
|
||||
checkBox = new JCheckBox( filter.getName() );
|
||||
checkBox.setSelected( filter.isEnabled() );
|
||||
}
|
||||
else if( userObject instanceof FilterElement )
|
||||
{
|
||||
FilterElement<?> element = (FilterElement<?>)userObject;
|
||||
|
||||
checkBox = new JCheckBox( element.getName() );
|
||||
checkBox.setSelected( element.isEnabled() );
|
||||
}
|
||||
|
||||
if( checkBox != null )
|
||||
{
|
||||
if( selected )
|
||||
{
|
||||
checkBox.setForeground( getTextSelectionColor() );
|
||||
checkBox.setBackground( getBackgroundSelectionColor() );
|
||||
}
|
||||
else
|
||||
{
|
||||
checkBox.setForeground( getTextNonSelectionColor() );
|
||||
checkBox.setBackground( getBackgroundNonSelectionColor() );
|
||||
}
|
||||
|
||||
return checkBox;
|
||||
}
|
||||
}
|
||||
|
||||
return super.getTreeCellRendererComponent( tree, treeNode, selected,
|
||||
expanded, leaf, row, hasFocus );
|
||||
}
|
||||
}
|
||||
|
||||
public class FilterCheckBox extends JCheckBox
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IFilter<T> mFilter;
|
||||
|
||||
public FilterCheckBox( IFilter<T> filter )
|
||||
{
|
||||
super( filter.getName() );
|
||||
|
||||
mFilter = filter;
|
||||
|
||||
setSelected( mFilter.isEnabled() );
|
||||
|
||||
addItemListener( new ItemListener()
|
||||
{
|
||||
@Override
|
||||
public void itemStateChanged( ItemEvent e )
|
||||
{
|
||||
mFilter.setEnabled( FilterCheckBox.this.isSelected() );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
public class FilterElementCheckBox extends JCheckBox
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private FilterElement<?> mFilter;
|
||||
|
||||
public FilterElementCheckBox( FilterElement<?> filter )
|
||||
{
|
||||
super( filter.getName() );
|
||||
|
||||
mFilter = filter;
|
||||
|
||||
setSelected( mFilter.isEnabled() );
|
||||
|
||||
addItemListener( new ItemListener()
|
||||
{
|
||||
@Override
|
||||
public void itemStateChanged( ItemEvent arg0 )
|
||||
{
|
||||
mFilter.setEnabled( FilterElementCheckBox.this.isSelected() );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
public class FilterTreeNodeEditor implements TreeCellEditor
|
||||
{
|
||||
@Override
|
||||
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||
public Component getTreeCellEditorComponent( JTree tree, Object node,
|
||||
boolean isSelected, boolean expanded, boolean leaf, int row )
|
||||
{
|
||||
if( node instanceof DefaultMutableTreeNode )
|
||||
{
|
||||
Object userObject = ((DefaultMutableTreeNode)node).getUserObject();
|
||||
|
||||
if( userObject instanceof IFilter )
|
||||
{
|
||||
return new FilterCheckBox( (IFilter)userObject );
|
||||
}
|
||||
else if( userObject instanceof FilterElement )
|
||||
{
|
||||
return new FilterElementCheckBox( (FilterElement<?>)userObject );
|
||||
}
|
||||
}
|
||||
|
||||
return new JLabel( node.toString() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCellEditorListener( CellEditorListener l ) {}
|
||||
|
||||
@Override
|
||||
public void cancelCellEditing()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCellEditorValue()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable( EventObject anEvent )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCellEditorListener( CellEditorListener l ) {}
|
||||
|
||||
@Override
|
||||
public boolean shouldSelectCell( EventObject anEvent )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopCellEditing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/filter/FilterElement.java
Normal file
49
src/filter/FilterElement.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package filter;
|
||||
|
||||
public class FilterElement<T> implements Comparable<FilterElement<T>>
|
||||
{
|
||||
private boolean mEnabled;
|
||||
private T mElement;
|
||||
|
||||
public FilterElement( T element, boolean enabled )
|
||||
{
|
||||
mElement = element;
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
public FilterElement( T t )
|
||||
{
|
||||
this( t, true );
|
||||
}
|
||||
|
||||
public T getElement()
|
||||
{
|
||||
return mElement;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
public void setEnabled( boolean enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return mElement.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo( FilterElement<T> other )
|
||||
{
|
||||
return toString().compareTo( other.toString() );
|
||||
}
|
||||
}
|
||||
97
src/filter/FilterSet.java
Normal file
97
src/filter/FilterSet.java
Normal file
@@ -0,0 +1,97 @@
|
||||
package filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FilterSet<T> implements IFilter<T>
|
||||
{
|
||||
protected List<IFilter<T>> mFilters = new ArrayList<IFilter<T>>();
|
||||
protected boolean mEnabled = true;
|
||||
protected String mName;
|
||||
|
||||
public FilterSet( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void setName( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passes( T t )
|
||||
{
|
||||
if( mEnabled )
|
||||
{
|
||||
for( IFilter<T> filter: mFilters )
|
||||
{
|
||||
if( filter.canProcess( t ) )
|
||||
{
|
||||
return filter.passes( t );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess( T t )
|
||||
{
|
||||
if( mEnabled )
|
||||
{
|
||||
for( IFilter<T> filter: mFilters )
|
||||
{
|
||||
if( filter.canProcess( t ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<IFilter<T>> getFilters()
|
||||
{
|
||||
return mFilters;
|
||||
}
|
||||
|
||||
public void addFilters( List<IFilter<T>> filters )
|
||||
{
|
||||
mFilters.addAll( filters );
|
||||
}
|
||||
|
||||
public void addFilter( IFilter<T> filter )
|
||||
{
|
||||
mFilters.add( filter );
|
||||
}
|
||||
|
||||
public void removeFilter( IFilter<T> filter )
|
||||
{
|
||||
mFilters.remove( filter );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled( boolean enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
}
|
||||
36
src/filter/IFilter.java
Normal file
36
src/filter/IFilter.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package filter;
|
||||
|
||||
public interface IFilter<T>
|
||||
{
|
||||
/**
|
||||
* Generic filter method.
|
||||
*
|
||||
* @param message - message to filter
|
||||
* @return - true if the message passes the filter
|
||||
*/
|
||||
public boolean passes( T t );
|
||||
|
||||
/**
|
||||
* Indicates if the filter can process (filter) the object
|
||||
*
|
||||
* @param message - candidate message for filtering
|
||||
*
|
||||
* @return - true if the filter is capable of filtering the message
|
||||
*/
|
||||
public boolean canProcess( T t );
|
||||
|
||||
/**
|
||||
* Indicates if this filter is enabled to evaluate messages
|
||||
*/
|
||||
public boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Sets the enabled state of the filter
|
||||
*/
|
||||
public void setEnabled( boolean enabled );
|
||||
|
||||
/**
|
||||
* Display name for the filter
|
||||
*/
|
||||
public String getName();
|
||||
}
|
||||
Reference in New Issue
Block a user