/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.impl.wsdl.panels.testsuite; import com.eviware.soapui.impl.wsdl.WsdlTestSuite; import com.eviware.soapui.impl.wsdl.actions.testsuite.AddNewTestCaseAction; import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarTestCaseAdapter; import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase; import com.eviware.soapui.model.ModelItem; import com.eviware.soapui.model.support.TestSuiteListenerAdapter; import com.eviware.soapui.model.testsuite.TestCase; 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; 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 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; /** * A panel showing a scrollable list of TestCases in a TestSuite. * * @author Ole.Matzura */ public class JTestSuiteTestCaseList extends JPanel { private Map<TestCase, TestCaseListPanel> panels = new HashMap<TestCase, TestCaseListPanel>(); private final WsdlTestSuite testSuite; private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener(); private TestCaseListPanel selectedTestCase; public JTestSuiteTestCaseList(WsdlTestSuite testSuite) { this.testSuite = testSuite; setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); for (int c = 0; c < testSuite.getTestCaseCount(); c++) { TestCaseListPanel testCaseListPanel = createTestCaseListPanel(testSuite.getTestCaseAt(c)); panels.put(testSuite.getTestCaseAt(c), testCaseListPanel); add(testCaseListPanel); } add(Box.createVerticalGlue()); setBackground(Color.WHITE); testSuite.addTestSuiteListener(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 TestCaseListDragAndDropable(this), DropType.AFTER); dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, dragAndDropHandler); } public void reset() { for (TestCaseListPanel testCasePanel : panels.values()) { testCasePanel.reset(); } } @Override public void addNotify() { super.addNotify(); testSuite.addTestSuiteListener(testSuiteListener); } @Override public void removeNotify() { super.removeNotify(); testSuite.removeTestSuiteListener(testSuiteListener); } private final class InternalTestSuiteListener extends TestSuiteListenerAdapter { public void testCaseAdded(TestCase testCase) { TestCaseListPanel testCaseListPanel = createTestCaseListPanel(testCase); panels.put(testCase, testCaseListPanel); add(testCaseListPanel, testCase.getTestSuite().getIndexOfTestCase(testCase)); revalidate(); repaint(); } public void testCaseRemoved(TestCase testCase) { TestCaseListPanel testCaseListPanel = panels.get(testCase); if (testCaseListPanel != null) { remove(testCaseListPanel); panels.remove(testCase); revalidate(); repaint(); } } @Override public void testCaseMoved(TestCase testCase, int index, int offset) { TestCaseListPanel testCaseListPanel = panels.get(testCase); if (testCaseListPanel != null) { boolean hadFocus = testCaseListPanel.hasFocus(); remove(testCaseListPanel); add(testCaseListPanel, index + offset); revalidate(); repaint(); if (hadFocus) { testCaseListPanel.requestFocus(); } } } } public final class TestCaseListPanel extends JPanel implements Autoscroll { private final WsdlTestCase testCase; private JProgressBar progressBar; private JLabel label; private ProgressBarTestCaseAdapter progressBarAdapter; private TestCasePropertyChangeListener testCasePropertyChangeListener; private AutoscrollSupport autoscrollSupport; public TestCaseListPanel(WsdlTestCase testCase) { super(new BorderLayout()); setFocusable(true); this.testCase = testCase; 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) { TestCaseListPanel.this.processMouseEvent(translateMouseEvent(e)); } } protected void processMouseMotionEvent(MouseEvent e) { TestCaseListPanel.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(TestCaseListPanel.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(testCase.getLabel()); label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); label.setInheritsPopupMenu(true); label.setEnabled(!testCase.isDisabled()); add(progressPanel, BorderLayout.CENTER); add(label, BorderLayout.NORTH); testCasePropertyChangeListener = new TestCasePropertyChangeListener(); initPopup(testCase); addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { requestFocus(); } public void mouseClicked(MouseEvent e) { if (e.getClickCount() < 2) { if (selectedTestCase != null) { selectedTestCase.setSelected(false); } setSelected(true); selectedTestCase = TestCaseListPanel.this; return; } UISupport.selectAndShow(TestCaseListPanel.this.testCase); } }); addKeyListener(new TestCaseListPanelKeyHandler()); // init border setSelected(false); } public void reset() { progressBar.setValue(0); progressBar.setString(""); } private void initPopup(WsdlTestCase testCase) { ActionList actions = ActionListBuilder.buildActions(testCase); actions.insertAction( SwingActionDelegate.createDelegate(AddNewTestCaseAction.SOAPUI_ACTION_ID, testSuite, null, null), 0); actions.insertAction(ActionSupport.SEPARATOR_ACTION, 1); setComponentPopupMenu(ActionSupport.buildPopup(actions)); } public void addNotify() { super.addNotify(); testCase.addPropertyChangeListener(testCasePropertyChangeListener); progressBarAdapter = new ProgressBarTestCaseAdapter(progressBar, testCase); } public void removeNotify() { super.removeNotify(); if (progressBarAdapter != null) { testCase.removePropertyChangeListener(testCasePropertyChangeListener); 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 selectedTestCase != null && selectedTestCase.getTestCase() == testCase; } private final class TestCasePropertyChangeListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(TestCase.LABEL_PROPERTY)) { label.setEnabled(!testCase.isDisabled()); label.setText(testCase.getLabel()); } else if (evt.getPropertyName().equals(TestCase.DISABLED_PROPERTY)) { initPopup(testCase); } } } protected TestCase getTestCase() { return testCase; } public ModelItem getModelItem() { return testCase; } public void autoscroll(Point pt) { int ix = getIndexOf(this); if (pt.getY() < 12 && ix > 0) { Rectangle bounds = JTestSuiteTestCaseList.this.getComponent(ix - 1).getBounds(); JTestSuiteTestCaseList.this.scrollRectToVisible(bounds); } else if (pt.getY() > getHeight() - 12 && ix < testSuite.getTestCaseCount() - 1) { Rectangle bounds = JTestSuiteTestCaseList.this.getComponent(ix + 1).getBounds(); JTestSuiteTestCaseList.this.scrollRectToVisible(bounds); } } public Insets getAutoscrollInsets() { return autoscrollSupport.getAutoscrollInsets(); } private final class TestCaseListPanelKeyHandler extends KeyAdapter { public void keyPressed(KeyEvent e) { if (e.getKeyChar() == KeyEvent.VK_ENTER) { UISupport.selectAndShow(testCase); e.consume(); } else { ActionList actions = ActionListBuilder.buildActions(testCase); if (actions != null) { actions.dispatchKeyEvent(e); } } } } } protected int getIndexOf(TestCaseListPanel panel) { return Arrays.asList(getComponents()).indexOf(panel); } protected TestCaseListPanel createTestCaseListPanel(TestCase testCase) { TestCaseListPanel testCaseListPanel = new TestCaseListPanel((WsdlTestCase) testCase); DragSource dragSource = DragSource.getDefaultDragSource(); SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler(new TestCaseListPanelDragAndDropable( testCaseListPanel), DropType.BEFORE_AND_AFTER); dragSource.createDefaultDragGestureRecognizer(testCaseListPanel, DnDConstants.ACTION_COPY_OR_MOVE, dragAndDropHandler); return testCaseListPanel; } private class TestCaseListDragAndDropable implements SoapUIDragAndDropable<ModelItem> { private final JTestSuiteTestCaseList list; public TestCaseListDragAndDropable(JTestSuiteTestCaseList 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 testCaseCount = testSuite.getTestCaseCount(); return testCaseCount == 0 ? testSuite : testSuite.getTestCaseAt(testCaseCount - 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 TestCaseListPanelDragAndDropable implements SoapUIDragAndDropable<ModelItem> { private final TestCaseListPanel testCasePanel; public TestCaseListPanelDragAndDropable(TestCaseListPanel testCasePanel) { this.testCasePanel = testCasePanel; } public JComponent getComponent() { return testCasePanel; } public void setDragInfo(String dropInfo) { testCasePanel.setToolTipText(dropInfo.length() == 0 ? null : dropInfo); } public Rectangle getModelItemBounds(ModelItem path) { return new Rectangle(testCasePanel.getSize()); } public ModelItem getModelItemForLocation(int x, int y) { return testCasePanel.getModelItem(); } public Component getRenderer(ModelItem path) { return null; } public void selectModelItem(ModelItem path) { testCasePanel.setSelected(!testCasePanel.isSelected()); } public void toggleExpansion(ModelItem last) { } } }