Package com.eviware.soapui.ui

Source Code of com.eviware.soapui.ui.Navigator$MultiActionInvoker

/*
*  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;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.dnd.Autoscroll;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.project.Project;
import com.eviware.soapui.model.tree.SoapUITreeModel;
import com.eviware.soapui.model.tree.SoapUITreeNode;
import com.eviware.soapui.model.tree.SoapUITreeNodeRenderer;
import com.eviware.soapui.model.tree.nodes.ProjectTreeNode;
import com.eviware.soapui.model.workspace.Workspace;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.SoapUIMultiAction;
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.components.JXToolBar;

/**
* The soapUI navigator tree
*
* @author Ole.Matzura
*/

public class Navigator extends JPanel
{
  private Workspace workspace;
  private JTree mainTree;
  private SoapUITreeModel treeModel;
  private Set<NavigatorListener> listeners = new HashSet<NavigatorListener>();

  public Navigator( Workspace workspace )
  {
    super( new BorderLayout() );
    this.workspace = workspace;

    buildUI();
  }

  private void buildUI()
  {
    treeModel = new SoapUITreeModel( workspace );

    mainTree = new NavigatorTree( treeModel );
    mainTree.setRootVisible( true );
    mainTree.setExpandsSelectedPaths( true );
    mainTree.setScrollsOnExpand( true );
    mainTree.setToggleClickCount( 0 );
    mainTree.addMouseListener( new TreeMouseListener() );
    mainTree.addTreeSelectionListener( new InternalTreeSelectionListener() );
    mainTree.setCellRenderer( new SoapUITreeNodeRenderer() );
    mainTree.setBorder( null );
    mainTree.getSelectionModel().setSelectionMode( TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION );
    mainTree.addKeyListener( new TreeKeyListener() );

    ToolTipManager.sharedInstance().registerComponent( mainTree );

    add( new JScrollPane( mainTree ), BorderLayout.CENTER );
    add( buildToolbar(), BorderLayout.NORTH );
    setBorder( BorderFactory.createEmptyBorder( 0, 0, 0, 0 ) );
  }

  private Component buildToolbar()
  {
    JXToolBar toolbar = UISupport.createSmallToolbar();

    JToggleButton toggleButton = new JToggleButton( new TogglePropertiesAction() );
    toggleButton.setToolTipText( "Toggles displaying of Test Properties in tree" );
    toggleButton.setSize( 10, 12 );
    toolbar.addFixed( toggleButton );
    toolbar.addGlue();

    return toolbar;
  }

  private static class NavigatorTree extends JTree implements Autoscroll
  {
    public NavigatorTree( SoapUITreeModel treeModel )
    {
      super( treeModel );
    }

    private static final int AUTOSCROLL_MARGIN = 12;

    public void autoscroll( Point pt )
    {
      // Figure out which row we�re on.
      int nRow = getRowForLocation( pt.x, pt.y );

      // If we are not on a row then ignore this autoscroll request
      if( nRow < 0 )
        return;

      Rectangle raOuter = getBounds();
      // Now decide if the row is at the top of the screen or at the
      // bottom. We do this to make the previous row (or the next
      // row) visible as appropriate. If we�re at the absolute top or
      // bottom, just return the first or last row respectively.

      nRow = ( pt.y + raOuter.y <= AUTOSCROLL_MARGIN ) // Is row at top of
      // screen?
      ? ( nRow <= 0 ? 0 : nRow - 1 ) // Yes, scroll up one row
          : ( nRow < getRowCount() - 1 ? nRow + 1 : nRow ); // No,
      // scroll
      // down one
      // row

      scrollRowToVisible( nRow );
    }

    // Calculate the insets for the *JTREE*, not the viewport
    // the tree is in. This makes it a bit messy.
    public Insets getAutoscrollInsets()
    {
      Rectangle raOuter = getBounds();
      Rectangle raInner = getParent().getBounds();
      return new Insets( raInner.y - raOuter.y + AUTOSCROLL_MARGIN, raInner.x - raOuter.x + AUTOSCROLL_MARGIN,
          raOuter.height - raInner.height - raInner.y + raOuter.y + AUTOSCROLL_MARGIN, raOuter.width
              - raInner.width - raInner.x + raOuter.x + AUTOSCROLL_MARGIN );
    }
  }

  public Project getCurrentProject()
  {
    TreePath path = mainTree.getSelectionPath();
    if( path == null )
      return null;

    Object node = ( Object )path.getLastPathComponent();
    while( node != null && !( node instanceof ProjectTreeNode ) )
    {
      path = path.getParentPath();
      node = ( path == null ? null : path.getLastPathComponent() );
    }

    if( node == null )
      return null;

    return ( ( ProjectTreeNode )node ).getProject();
  }

  public void addNavigatorListener( NavigatorListener listener )
  {
    listeners.add( listener );
  }

  public void removeNavigatorListener( NavigatorListener listener )
  {
    listeners.remove( listener );
  }

  public void selectModelItem( ModelItem modelItem )
  {
    TreePath path = treeModel.getPath( modelItem );
    mainTree.setSelectionPath( path );
    mainTree.expandPath( path );
    mainTree.scrollPathToVisible( path );
  }

  public TreePath getTreePath( ModelItem modelItem )
  {
    return treeModel.getPath( modelItem );
  }

  public JTree getMainTree()
  {
    return mainTree;
  }

  public ModelItem getSelectedItem()
  {
    TreePath path = mainTree.getSelectionPath();
    if( path == null )
      return null;

    return ( ( SoapUITreeNode )path.getLastPathComponent() ).getModelItem();
  }

  private final class TreeKeyListener extends KeyAdapter
  {
    public void keyPressed( KeyEvent e )
    {
      TreePath selectionPath = mainTree.getSelectionPath();
      if( selectionPath == null || mainTree.getSelectionCount() == 0 )
        return;

      if( mainTree.getSelectionCount() == 1 )
      {
        SoapUITreeNode lastPathComponent = ( SoapUITreeNode )selectionPath.getLastPathComponent();
        ActionList actions = lastPathComponent.getActions();
        if( actions != null )
        {
          actions.dispatchKeyEvent( e );
        }

        if( !e.isConsumed() )
        {
          KeyStroke ks = KeyStroke.getKeyStrokeForEvent( e );
          if( ks.equals( UISupport.getKeyStroke( "alt C" ) ) )
          {
            mainTree.collapsePath( selectionPath );
            e.consume();
          }
          else if( ks.equals( UISupport.getKeyStroke( "alt E" ) ) )
          {
            mainTree.collapsePath( selectionPath );
            int row = mainTree.getSelectionRows()[0];
            TreePath nextPath = mainTree.getPathForRow( row + 1 );

            TreePath path = mainTree.getPathForRow( row );
            while( path != null && !path.equals( nextPath ) )
            {
              mainTree.expandRow( row );
              path = mainTree.getPathForRow( ++row );
            }

            e.consume();
          }
        }
      }
      else
      {
        TreePath[] selectionPaths = mainTree.getSelectionPaths();
        List<ModelItem> targets = new ArrayList<ModelItem>();
        for( TreePath treePath : selectionPaths )
        {
          SoapUITreeNode node = ( SoapUITreeNode )treePath.getLastPathComponent();
          targets.add( node.getModelItem() );
        }

        if( targets.size() > 0 )
        {
          ActionList actions = ActionListBuilder
              .buildMultiActions( targets.toArray( new ModelItem[targets.size()] ) );
          if( actions.getActionCount() > 0 )
          {
            actions.dispatchKeyEvent( e );
          }
        }
      }
    }
  }

  public class InternalTreeSelectionListener implements TreeSelectionListener
  {
    public void valueChanged( TreeSelectionEvent e )
    {
      Object obj = e.getPath().getLastPathComponent();
      if( obj instanceof SoapUITreeNode )
      {
        SoapUITreeNode treeNode = ( SoapUITreeNode )obj;

        if( !listeners.isEmpty() )
        {
          TreePath newPath = e.getNewLeadSelectionPath();
          NavigatorListener[] array = listeners.toArray( new NavigatorListener[listeners.size()] );
          for( NavigatorListener listener : array )
          {
            listener.nodeSelected( newPath == null ? null : treeNode );
          }
        }
      }
    }
  }

  public class TreeMouseListener extends MouseAdapter
  {
    private final class CollapseRowAction extends AbstractAction
    {
      private final int row;

      public CollapseRowAction( int row )
      {
        this.row = row;
      }

      public void actionPerformed( ActionEvent e )
      {
        collapseAll( mainTree.getPathForRow( row ) );
        mainTree.collapseRow( row );
      }

      private void collapseAll( TreePath tp )
      {
        if( tp == null )
          return;

        Object node = tp.getLastPathComponent();
        TreeModel model = mainTree.getModel();
        if( !model.isLeaf( node ) )
        {
          mainTree.collapsePath( tp );
          for( int i = 0; i < model.getChildCount( node ); i++ )
          {
            // for (int i = node.childCount()-4;i>=0;i--){
            collapseAll( tp.pathByAddingChild( model.getChild( node, i ) ) );
          }
          mainTree.collapsePath( tp );
        }
      }
    }

    private final class ExpandRowAction extends AbstractAction
    {
      private final int row;

      public ExpandRowAction( int row )
      {
        this.row = row;
      }

      public void actionPerformed( ActionEvent e )
      {
        mainTree.expandRow( row );
        expandAll( mainTree.getPathForRow( row ) );
      }

      private void expandAll( TreePath tp )
      {
        if( tp == null )
          return;

        Object node = tp.getLastPathComponent();
        TreeModel model = mainTree.getModel();
        if( !model.isLeaf( node ) )
        {
          mainTree.expandPath( tp );
          for( int i = 0; i < model.getChildCount( node ); i++ )
          {
            expandAll( tp.pathByAddingChild( model.getChild( node, i ) ) );
          }
        }
      }

    }

    private ActionList actions;

    public void mouseClicked( MouseEvent e )
    {
      if( e.isPopupTrigger() )
        showPopup( e );
      else if( e.getClickCount() < 2 )
        return;
      if( mainTree.getSelectionCount() == 1 )
      {
        int row = mainTree.getRowForLocation( e.getX(), e.getY() );
        TreePath path = mainTree.getSelectionPath();
        if( path == null && row == -1 )
          return;

        if( path == null || mainTree.getRowForPath( path ) != row )
          mainTree.setSelectionRow( row );

        SoapUITreeNode node = ( SoapUITreeNode )path.getLastPathComponent();
        actions = node.getActions();
        if( actions != null )
        {
          SwingUtilities.invokeLater( new Runnable()
          {
            public void run()
            {
              if( actions != null )
              {
                actions.performDefaultAction( new ActionEvent( mainTree, 0, null ) );
                actions = null;
              }
            }
          } );
        }
      }
    }

    public void mousePressed( MouseEvent e )
    {
      if( e.isPopupTrigger() )
        showPopup( e );
    }

    public void mouseReleased( MouseEvent e )
    {
      if( e.isPopupTrigger() )
        showPopup( e );
    }

    private void showPopup( MouseEvent e )
    {
      if( mainTree.getSelectionCount() < 2 )
      {
        TreePath path = mainTree.getPathForLocation( ( int )e.getPoint().getX(), ( int )e.getPoint().getY() );
        if( path == null )
        {
          int row = ( int )e.getPoint().getY() / mainTree.getRowHeight();
          if( row != -1 )
          {
            JPopupMenu collapsePopup = new JPopupMenu();
            collapsePopup.add( "Collapse" ).addActionListener( new CollapseRowAction( row ) );
            collapsePopup.add( "Expand" ).addActionListener( new ExpandRowAction( row ) );
            collapsePopup.show( mainTree, e.getX(), e.getY() );
          }

          return;
        }
        SoapUITreeNode node = ( SoapUITreeNode )path.getLastPathComponent();

        JPopupMenu popupMenu = node.getPopup();
        if( popupMenu == null )
          return;

        mainTree.setSelectionPath( path );

        popupMenu.show( mainTree, e.getX(), e.getY() );
      }
      else
      {
        TreePath[] selectionPaths = mainTree.getSelectionPaths();
        List<ModelItem> targets = new ArrayList<ModelItem>();
        for( TreePath treePath : selectionPaths )
        {
          SoapUITreeNode node = ( SoapUITreeNode )treePath.getLastPathComponent();
          targets.add( node.getModelItem() );
        }

        if( targets.size() > 0 )
        {
          ActionList actions = ActionListBuilder
              .buildMultiActions( targets.toArray( new ModelItem[targets.size()] ) );
          if( actions.getActionCount() > 0 )
          {
            JPopupMenu popup = new JPopupMenu();
            ActionSupport.addActions( actions, popup );
            popup.show( mainTree, e.getX(), e.getY() );
          }
        }
      }
    }
  }

  public boolean isVisible( TreePath path )
  {
    return mainTree.isVisible( path );
  }

  public boolean isExpanded( TreePath path )
  {
    return mainTree.isExpanded( path );
  }

  private class TogglePropertiesAction extends AbstractAction
  {
    public TogglePropertiesAction()
    {
      putValue( SMALL_ICON, UISupport.createImageIcon( "/toggle_properties.gif" ) );
    }

    public void actionPerformed( ActionEvent e )
    {
      Enumeration<TreePath> expandedDescendants = mainTree.getExpandedDescendants( getTreePath( workspace ) );
      TreePath selectionPath = mainTree.getSelectionPath();

      treeModel.setShowProperties( !treeModel.isShowProperties() );

      while( expandedDescendants != null && expandedDescendants.hasMoreElements() )
      {
        mainTree.expandPath( expandedDescendants.nextElement() );
      }

      if( selectionPath != null )
        mainTree.setSelectionPath( selectionPath );
    }
  }

  public class MultiActionInvoker extends AbstractAction
  {
    private final SoapUIMultiAction action;
    private final List<ModelItem> targets;

    public MultiActionInvoker( SoapUIMultiAction action, List<ModelItem> targets )
    {
      super( action.getName() );

      this.action = action;
      this.targets = targets;
    }

    public void actionPerformed( ActionEvent e )
    {
      action.perform( targets.toArray( new ModelItem[targets.size()] ), null );
    }
  }
}
TOP

Related Classes of com.eviware.soapui.ui.Navigator$MultiActionInvoker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.