/*
* 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.ui.desktop.standalone;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.PanelBuilder;
import com.eviware.soapui.model.util.PanelBuilderRegistry;
import com.eviware.soapui.model.workspace.Workspace;
import com.eviware.soapui.settings.UISettings;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.swing.ActionList;
import com.eviware.soapui.support.action.swing.DefaultActionList;
import com.eviware.soapui.ui.desktop.AbstractSoapUIDesktop;
import com.eviware.soapui.ui.desktop.DesktopPanel;
import com.eviware.soapui.ui.desktop.SoapUIDesktop;
/**
* The default standalone soapUI desktop using a JDesktopPane
*
* @author Ole.Matzura
*/
public class StandaloneDesktop extends AbstractSoapUIDesktop
{
private JDesktopPane desktopPane;
private Map<ModelItem, JInternalFrame> modelItemToInternalFrameMap = new HashMap<ModelItem, JInternalFrame>();
private Map<JInternalFrame, DesktopPanel> internalFrameToDesktopPanelMap = new HashMap<JInternalFrame, DesktopPanel>();
private DesktopPanelPropertyChangeListener desktopPanelPropertyChangeListener = new DesktopPanelPropertyChangeListener();
private InternalDesktopFrameListener internalFrameListener = new InternalDesktopFrameListener();
private ActionList actions;
private DesktopPanel currentPanel;
private CloseCurrentAction closeCurrentAction = new CloseCurrentAction();
private CloseOtherAction closeOtherAction = new CloseOtherAction();
private CloseAllAction closeAllAction = new CloseAllAction();
private static int openFrameCount = 0;
private static final int xOffset = 30, yOffset = 30;
private JPanel desktopPanel = new JPanel( new BorderLayout() );
private boolean transferring;
public StandaloneDesktop( Workspace workspace )
{
super( workspace );
buildUI();
actions = new DefaultActionList( "Desktop" );
actions.addAction( closeCurrentAction );
actions.addAction( closeOtherAction );
actions.addAction( closeAllAction );
enableWindowActions();
}
private void enableWindowActions()
{
closeCurrentAction.setEnabled( currentPanel != null && internalFrameToDesktopPanelMap.size() > 0 );
closeOtherAction.setEnabled( currentPanel != null && internalFrameToDesktopPanelMap.size() > 1 );
closeAllAction.setEnabled( internalFrameToDesktopPanelMap.size() > 0 );
}
private void buildUI()
{
desktopPane = new SoapUIDesktopPane();
JScrollPane scrollPane = new JScrollPane( desktopPane );
desktopPanel.add( scrollPane, BorderLayout.CENTER );
}
public JComponent getDesktopComponent()
{
return desktopPanel;
}
public boolean closeDesktopPanel( DesktopPanel desktopPanel )
{
try
{
if( desktopPanel.getModelItem() != null )
{
return closeDesktopPanel( desktopPanel.getModelItem() );
}
else
{
JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
if( frame != null )
{
frame.doDefaultCloseAction();
return frame.isClosed();
}
// else
// throw new RuntimeException( "Cannot close unkown DesktopPanel: "
// + desktopPanel.getTitle() );
return false;
}
}
finally
{
enableWindowActions();
}
}
private JInternalFrame getFrameForDesktopPanel( DesktopPanel desktopPanel )
{
for( JInternalFrame frame : internalFrameToDesktopPanelMap.keySet() )
{
if( internalFrameToDesktopPanelMap.get( frame ) == desktopPanel )
{
return frame;
}
}
return null;
}
public boolean hasDesktopPanel( ModelItem modelItem )
{
return modelItemToInternalFrameMap.containsKey( modelItem );
}
public DesktopPanel showDesktopPanel( ModelItem modelItem )
{
PanelBuilder<ModelItem> panelBuilder = PanelBuilderRegistry.getPanelBuilder( modelItem );
if( modelItemToInternalFrameMap.containsKey( modelItem ) )
{
JInternalFrame frame = modelItemToInternalFrameMap.get( modelItem );
try
{
desktopPane.getDesktopManager().deiconifyFrame( frame );
frame.setSelected( true );
frame.moveToFront();
currentPanel = internalFrameToDesktopPanelMap.get( frame );
}
catch( PropertyVetoException e )
{
SoapUI.logError( e );
}
}
else if( panelBuilder != null && panelBuilder.hasDesktopPanel() )
{
DesktopPanel desktopPanel = panelBuilder.buildDesktopPanel( modelItem );
if( desktopPanel == null )
return null;
JInternalFrame frame = createContentFrame( desktopPanel );
desktopPane.add( frame );
try
{
frame.setSelected( true );
}
catch( PropertyVetoException e )
{
SoapUI.logError( e );
}
modelItemToInternalFrameMap.put( modelItem, frame );
internalFrameToDesktopPanelMap.put( frame, desktopPanel );
fireDesktopPanelCreated( desktopPanel );
currentPanel = desktopPanel;
desktopPanel.getComponent().requestFocusInWindow();
}
else
Toolkit.getDefaultToolkit().beep();
enableWindowActions();
return currentPanel;
}
private JInternalFrame createContentFrame( DesktopPanel desktopPanel )
{
desktopPanel.addPropertyChangeListener( desktopPanelPropertyChangeListener );
JComponent panel = desktopPanel.getComponent();
panel.setOpaque( true );
String title = desktopPanel.getTitle();
JInternalFrame frame = new JInternalFrame( title, true, true, true, true );
frame.addInternalFrameListener( internalFrameListener );
frame.setContentPane( panel );
frame.setSize( panel.getPreferredSize() );
frame.setVisible( true );
frame.setFrameIcon( desktopPanel.getIcon() );
frame.setToolTipText( desktopPanel.getDescription() );
frame.setDefaultCloseOperation( JInternalFrame.DO_NOTHING_ON_CLOSE );
frame.setLocation( xOffset * ( openFrameCount % 10 ), yOffset * ( openFrameCount % 10 ) );
if( !SoapUI.getSettings().getBoolean( UISettings.NATIVE_LAF ) )
{
// This creates an empty frame on Mac OS X native L&F.
frame.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createRaisedBevelBorder(),
BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) ) );
}
openFrameCount++ ;
return frame;
}
public boolean closeDesktopPanel( ModelItem modelItem )
{
try
{
if( modelItemToInternalFrameMap.containsKey( modelItem ) )
{
JInternalFrame frame = modelItemToInternalFrameMap.get( modelItem );
frame.doDefaultCloseAction();
return frame.isClosed();
}
return false;
}
finally
{
enableWindowActions();
}
}
private class InternalDesktopFrameListener extends InternalFrameAdapter
{
public void internalFrameClosing( InternalFrameEvent e )
{
DesktopPanel desktopPanel = internalFrameToDesktopPanelMap.get( e.getInternalFrame() );
if( !transferring && !desktopPanel.onClose( true ) )
{
return;
}
desktopPanel.removePropertyChangeListener( desktopPanelPropertyChangeListener );
modelItemToInternalFrameMap.remove( desktopPanel.getModelItem() );
internalFrameToDesktopPanelMap.remove( e.getInternalFrame() );
// replace content frame to make sure it is released
e.getInternalFrame().setContentPane( new JPanel() );
e.getInternalFrame().dispose();
if( !transferring )
fireDesktopPanelClosed( desktopPanel );
if( currentPanel == desktopPanel )
currentPanel = null;
}
public void internalFrameActivated( InternalFrameEvent e )
{
currentPanel = internalFrameToDesktopPanelMap.get( e.getInternalFrame() );
if( currentPanel != null )
{
fireDesktopPanelSelected( currentPanel );
}
enableWindowActions();
}
public void internalFrameDeactivated( InternalFrameEvent e )
{
currentPanel = null;
enableWindowActions();
}
}
public class CloseCurrentAction extends AbstractAction
{
public CloseCurrentAction()
{
super( "Close Current" );
putValue( Action.SHORT_DESCRIPTION, "Closes the current window" );
putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu F4" ) );
}
public void actionPerformed( ActionEvent e )
{
JInternalFrame frame = desktopPane.getSelectedFrame();
if( frame != null )
closeDesktopPanel( internalFrameToDesktopPanelMap.get( frame ) );
}
}
public class CloseOtherAction extends AbstractAction
{
public CloseOtherAction()
{
super( "Close Others" );
putValue( Action.SHORT_DESCRIPTION, "Closes all windows except the current one" );
putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu alt O" ) );
}
public void actionPerformed( ActionEvent e )
{
JInternalFrame frame = desktopPane.getSelectedFrame();
if( frame == null )
return;
JInternalFrame[] frames = internalFrameToDesktopPanelMap.keySet().toArray(
new JInternalFrame[internalFrameToDesktopPanelMap.size()] );
for( JInternalFrame f : frames )
{
if( f != frame )
{
closeDesktopPanel( internalFrameToDesktopPanelMap.get( f ) );
}
}
}
}
public class CloseAllAction extends AbstractAction
{
public CloseAllAction()
{
super( "Close All" );
putValue( Action.SHORT_DESCRIPTION, "Closes all windows" );
putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu alt L" ) );
}
public void actionPerformed( ActionEvent e )
{
closeAll();
}
}
public ActionList getActions()
{
return actions;
}
private class DesktopPanelPropertyChangeListener implements PropertyChangeListener
{
public void propertyChange( PropertyChangeEvent evt )
{
DesktopPanel desktopPanel = ( DesktopPanel )evt.getSource();
JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
if( frame != null )
{
if( evt.getPropertyName().equals( DesktopPanel.TITLE_PROPERTY ) )
{
frame.setTitle( desktopPanel.getTitle() );
}
else if( evt.getPropertyName().equals( DesktopPanel.ICON_PROPERTY ) )
{
frame.setFrameIcon( desktopPanel.getIcon() );
}
}
}
}
public DesktopPanel[] getDesktopPanels()
{
return internalFrameToDesktopPanelMap.values().toArray( new DesktopPanel[internalFrameToDesktopPanelMap.size()] );
}
public DesktopPanel getDesktopPanel( ModelItem modelItem )
{
return internalFrameToDesktopPanelMap.get( modelItem );
}
public DesktopPanel showDesktopPanel( DesktopPanel desktopPanel )
{
JInternalFrame frame = getFrameForDesktopPanel( desktopPanel );
if( frame != null )
{
try
{
desktopPane.getDesktopManager().deiconifyFrame( frame );
frame.setSelected( true );
frame.moveToFront();
}
catch( Exception e )
{
SoapUI.logError( e );
}
}
else
{
frame = createContentFrame( desktopPanel );
desktopPane.add( frame );
if( desktopPanel.getModelItem() != null )
modelItemToInternalFrameMap.put( desktopPanel.getModelItem(), frame );
internalFrameToDesktopPanelMap.put( frame, desktopPanel );
fireDesktopPanelCreated( desktopPanel );
frame.moveToFront();
desktopPanel.getComponent().requestFocusInWindow();
}
currentPanel = desktopPanel;
enableWindowActions();
return desktopPanel;
}
class SoapUIDesktopPane extends JDesktopPane
{
Image img;
private int imageWidth;
private int imageHeight;
public SoapUIDesktopPane()
{
try
{
File file = new File( "soapui-background.gif" );
if( !file.exists() )
file = new File( "soapui-background.jpg" );
if( !file.exists() )
file = new File( "soapui-background.png" );
if( file.exists() )
{
img = javax.imageio.ImageIO.read( file );
imageWidth = img.getWidth( this );
imageHeight = img.getHeight( this );
}
}
catch( Exception e )
{
}
}
public void paintComponent( Graphics g )
{
super.paintComponent( g );
if( img == null )
return;
int x = ( this.getWidth() - imageWidth ) / 2;
int y = ( this.getHeight() - imageHeight ) / 2;
g.drawImage( img, x, y, imageWidth, imageHeight, this );
}
}
public void transferTo( SoapUIDesktop newDesktop )
{
transferring = true;
List<DesktopPanel> values = new ArrayList<DesktopPanel>( internalFrameToDesktopPanelMap.values() );
for( DesktopPanel desktopPanel : values )
{
closeDesktopPanel( desktopPanel );
newDesktop.showDesktopPanel( desktopPanel );
}
transferring = false;
}
public boolean closeAll()
{
while( internalFrameToDesktopPanelMap.size() > 0 )
{
Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap.keySet().iterator();
try
{
i.next().setClosed( true );
}
catch( PropertyVetoException e1 )
{
SoapUI.logError( e1 );
}
}
internalFrameToDesktopPanelMap.clear();
modelItemToInternalFrameMap.clear();
JInternalFrame[] allFrames = desktopPane.getAllFrames();
for( JInternalFrame frame : allFrames )
{
frame.doDefaultCloseAction();
}
enableWindowActions();
return true;
}
public void minimize( DesktopPanel desktopPanel )
{
try
{
getFrameForDesktopPanel( desktopPanel ).setIcon( true );
}
catch( PropertyVetoException e )
{
SoapUI.logError( e );
}
}
public void maximize( DesktopPanel desktopPanel )
{
desktopPane.getDesktopManager().maximizeFrame( getFrameForDesktopPanel( desktopPanel ) );
}
}