/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI 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 Lesser General Public License for more details at gnu.org.
*/
package com.eviware.soapui.impl.wsdl.panels.project;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.dnd.Autoscroll;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragSource;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
import com.eviware.soapui.impl.wsdl.actions.project.AddNewTestSuiteAction;
import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarTestSuiteAdapter;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.support.ProjectListenerAdapter;
import com.eviware.soapui.model.testsuite.TestSuite;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.swing.ActionList;
import com.eviware.soapui.support.action.swing.ActionListBuilder;
import com.eviware.soapui.support.action.swing.ActionSupport;
import com.eviware.soapui.support.action.swing.SwingActionDelegate;
import com.eviware.soapui.support.dnd.DropType;
import com.eviware.soapui.support.dnd.SoapUIDragAndDropHandler;
import com.eviware.soapui.support.dnd.SoapUIDragAndDropable;
import com.eviware.soapui.support.swing.AutoscrollSupport;
/**
* A panel showing a scrollable list of TestSuites in a Project.
*
* @author Ole.Matzura
*/
public class JProjectTestSuiteList extends JPanel
{
private Map<TestSuite, TestSuiteListPanel> panels = new HashMap<TestSuite, TestSuiteListPanel>();
private final WsdlProject project;
private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
private TestSuiteListPanel selectedTestSuite;
public JProjectTestSuiteList( WsdlProject testSuite )
{
this.project = testSuite;
setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) );
for( int c = 0; c < testSuite.getTestSuiteCount(); c++ )
{
TestSuiteListPanel testSuiteListPanel = createTestSuiteListPanel( testSuite.getTestSuiteAt( c ) );
panels.put( testSuite.getTestSuiteAt( c ), testSuiteListPanel );
add( testSuiteListPanel );
}
add( Box.createVerticalGlue() );
setBackground( Color.WHITE );
testSuite.addProjectListener( testSuiteListener );
ActionList actions = ActionListBuilder.buildActions( testSuite );
actions.removeAction( 0 );
actions.removeAction( 0 );
setComponentPopupMenu( ActionSupport.buildPopup( actions ) );
DragSource dragSource = DragSource.getDefaultDragSource();
SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler( new TestSuiteListDragAndDropable(
this ), DropType.AFTER );
dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_COPY_OR_MOVE, dragAndDropHandler );
}
public void reset()
{
for( TestSuiteListPanel testSuitePanel : panels.values() )
{
testSuitePanel.reset();
}
}
@Override
public void addNotify()
{
super.addNotify();
project.addProjectListener( testSuiteListener );
}
@Override
public void removeNotify()
{
super.removeNotify();
project.removeProjectListener( testSuiteListener );
}
private final class InternalTestSuiteListener extends ProjectListenerAdapter
{
public void testSuiteAdded( TestSuite testSuite )
{
TestSuiteListPanel testSuiteListPanel = createTestSuiteListPanel( testSuite );
panels.put( testSuite, testSuiteListPanel );
add( testSuiteListPanel, testSuite.getProject().getIndexOfTestSuite( testSuite ) );
revalidate();
repaint();
}
public void testSuiteRemoved( TestSuite testSuite )
{
TestSuiteListPanel testSuiteListPanel = panels.get( testSuite );
if( testSuiteListPanel != null )
{
remove( testSuiteListPanel );
panels.remove( testSuite );
revalidate();
repaint();
}
}
public void testSuiteMoved( TestSuite testSuite, int index, int offset )
{
TestSuiteListPanel testSuiteListPanel = panels.get( testSuite );
if( testSuiteListPanel != null )
{
boolean hadFocus = testSuiteListPanel.hasFocus();
remove( testSuiteListPanel );
add( testSuiteListPanel, index + offset );
revalidate();
repaint();
if( hadFocus )
testSuiteListPanel.requestFocus();
}
}
}
public final class TestSuiteListPanel extends JPanel implements Autoscroll
{
private final WsdlTestSuite testSuite;
private JProgressBar progressBar;
private JLabel label;
private ProgressBarTestSuiteAdapter progressBarAdapter;
private TestSuitePropertyChangeListener testSuitePropertyChangeListener;
private AutoscrollSupport autoscrollSupport;
public TestSuiteListPanel( WsdlTestSuite testSuite )
{
super( new BorderLayout() );
setFocusable( true );
this.testSuite = testSuite;
autoscrollSupport = new AutoscrollSupport( this );
progressBar = new JProgressBar( 0, 100 )
{
protected void processMouseEvent( MouseEvent e )
{
if( e.getID() == MouseEvent.MOUSE_PRESSED || e.getID() == MouseEvent.MOUSE_RELEASED )
{
TestSuiteListPanel.this.processMouseEvent( translateMouseEvent( e ) );
}
}
protected void processMouseMotionEvent( MouseEvent e )
{
TestSuiteListPanel.this.processMouseMotionEvent( translateMouseEvent( e ) );
}
/**
* Translates the given mouse event to the enclosing map panel's
* coordinate space.
*/
private MouseEvent translateMouseEvent( MouseEvent e )
{
return new MouseEvent( TestSuiteListPanel.this, e.getID(), e.getWhen(), e.getModifiers(), e.getX()
+ getX(), e.getY() + getY(), e.getClickCount(), e.isPopupTrigger(), e.getButton() );
}
};
JPanel progressPanel = UISupport.createProgressBarPanel( progressBar, 5, false );
progressBar.setMinimumSize( new Dimension( 0, 10 ) );
progressBar.setBackground( Color.WHITE );
progressBar.setInheritsPopupMenu( true );
label = new JLabel( testSuite.getLabel() );
label.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
label.setInheritsPopupMenu( true );
label.setEnabled( !testSuite.isDisabled() );
add( progressPanel, BorderLayout.CENTER );
add( label, BorderLayout.NORTH );
testSuitePropertyChangeListener = new TestSuitePropertyChangeListener();
initPopup( testSuite );
addMouseListener( new MouseAdapter()
{
@Override
public void mousePressed( MouseEvent e )
{
requestFocus();
}
public void mouseClicked( MouseEvent e )
{
if( e.getClickCount() < 2 )
{
if( selectedTestSuite != null )
selectedTestSuite.setSelected( false );
setSelected( true );
selectedTestSuite = TestSuiteListPanel.this;
return;
}
UISupport.selectAndShow( TestSuiteListPanel.this.testSuite );
}
} );
addKeyListener( new TestSuiteListPanelKeyHandler() );
// init border
setSelected( false );
}
public void reset()
{
progressBar.setValue( 0 );
progressBar.setString( "" );
}
private void initPopup( WsdlTestSuite testSuite )
{
ActionList actions = ActionListBuilder.buildActions( testSuite );
actions.insertAction(
SwingActionDelegate.createDelegate( AddNewTestSuiteAction.SOAPUI_ACTION_ID, project, null, null ), 0 );
actions.insertAction( ActionSupport.SEPARATOR_ACTION, 1 );
setComponentPopupMenu( ActionSupport.buildPopup( actions ) );
}
public void addNotify()
{
super.addNotify();
testSuite.addPropertyChangeListener( testSuitePropertyChangeListener );
progressBarAdapter = new ProgressBarTestSuiteAdapter( progressBar, testSuite );
}
public void removeNotify()
{
super.removeNotify();
if( progressBarAdapter != null )
{
testSuite.removePropertyChangeListener( testSuitePropertyChangeListener );
progressBarAdapter.release();
progressBarAdapter = null;
}
}
public Dimension getMaximumSize()
{
Dimension size = super.getMaximumSize();
size.height = 50;
return size;
}
public void setSelected( boolean selected )
{
if( selected )
{
setBorder( BorderFactory.createLineBorder( Color.GRAY ) );
}
else
{
setBorder( BorderFactory.createLineBorder( Color.WHITE ) );
}
}
public boolean isSelected()
{
return selectedTestSuite != null && selectedTestSuite.getTestSuite() == testSuite;
}
private final class TestSuitePropertyChangeListener implements PropertyChangeListener
{
public void propertyChange( PropertyChangeEvent evt )
{
if( evt.getPropertyName().equals( TestSuite.LABEL_PROPERTY ) )
{
label.setEnabled( !testSuite.isDisabled() );
label.setText( testSuite.getLabel() );
}
else if( evt.getPropertyName().equals( TestSuite.DISABLED_PROPERTY ) )
{
initPopup( testSuite );
}
}
}
protected WsdlTestSuite getTestSuite()
{
return testSuite;
}
public ModelItem getModelItem()
{
return testSuite;
}
public void autoscroll( Point pt )
{
int ix = getIndexOf( this );
if( pt.getY() < 12 && ix > 0 )
{
Rectangle bounds = JProjectTestSuiteList.this.getComponent( ix - 1 ).getBounds();
JProjectTestSuiteList.this.scrollRectToVisible( bounds );
}
else if( pt.getY() > getHeight() - 12 && ix < project.getTestSuiteCount() - 1 )
{
Rectangle bounds = JProjectTestSuiteList.this.getComponent( ix + 1 ).getBounds();
JProjectTestSuiteList.this.scrollRectToVisible( bounds );
}
}
public Insets getAutoscrollInsets()
{
return autoscrollSupport.getAutoscrollInsets();
}
private final class TestSuiteListPanelKeyHandler extends KeyAdapter
{
public void keyPressed( KeyEvent e )
{
if( e.getKeyChar() == KeyEvent.VK_ENTER )
{
UISupport.selectAndShow( testSuite );
e.consume();
}
else
{
ActionList actions = ActionListBuilder.buildActions( testSuite );
if( actions != null )
actions.dispatchKeyEvent( e );
}
}
}
}
protected int getIndexOf( TestSuiteListPanel panel )
{
return Arrays.asList( getComponents() ).indexOf( panel );
}
protected TestSuiteListPanel createTestSuiteListPanel( TestSuite testSuite )
{
TestSuiteListPanel testSuiteListPanel = new TestSuiteListPanel( ( WsdlTestSuite )testSuite );
DragSource dragSource = DragSource.getDefaultDragSource();
SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler(
new TestSuiteListPanelDragAndDropable( testSuiteListPanel ), DropType.BEFORE_AND_AFTER );
dragSource.createDefaultDragGestureRecognizer( testSuiteListPanel, DnDConstants.ACTION_COPY_OR_MOVE,
dragAndDropHandler );
return testSuiteListPanel;
}
private class TestSuiteListDragAndDropable implements SoapUIDragAndDropable<ModelItem>
{
private final JProjectTestSuiteList list;
public TestSuiteListDragAndDropable( JProjectTestSuiteList list )
{
this.list = list;
}
public JComponent getComponent()
{
return list;
}
public Rectangle getModelItemBounds( ModelItem modelItem )
{
return list.getBounds();
}
public ModelItem getModelItemForLocation( int x, int y )
{
int testSuiteCount = project.getTestSuiteCount();
return testSuiteCount == 0 ? project : project.getTestSuiteAt( testSuiteCount - 1 );
}
public Component getRenderer( ModelItem modelItem )
{
return null;
}
public void selectModelItem( ModelItem modelItem )
{
}
public void setDragInfo( String dropInfo )
{
list.setToolTipText( dropInfo );
}
public void toggleExpansion( ModelItem modelItem )
{
}
}
private static class TestSuiteListPanelDragAndDropable implements SoapUIDragAndDropable<ModelItem>
{
private final TestSuiteListPanel testSuitePanel;
public TestSuiteListPanelDragAndDropable( TestSuiteListPanel testSuitePanel )
{
this.testSuitePanel = testSuitePanel;
}
public JComponent getComponent()
{
return testSuitePanel;
}
public void setDragInfo( String dropInfo )
{
testSuitePanel.setToolTipText( dropInfo.length() == 0 ? null : dropInfo );
}
public Rectangle getModelItemBounds( ModelItem path )
{
return new Rectangle( testSuitePanel.getSize() );
}
public ModelItem getModelItemForLocation( int x, int y )
{
return testSuitePanel.getModelItem();
}
public Component getRenderer( ModelItem path )
{
return null;
}
public void selectModelItem( ModelItem path )
{
testSuitePanel.setSelected( !testSuitePanel.isSelected() );
}
public void toggleExpansion( ModelItem last )
{
}
}
}