1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.project;
14
15 import java.awt.BorderLayout;
16 import java.awt.Color;
17 import java.awt.Component;
18 import java.awt.Dimension;
19 import java.awt.Insets;
20 import java.awt.Point;
21 import java.awt.Rectangle;
22 import java.awt.dnd.Autoscroll;
23 import java.awt.dnd.DnDConstants;
24 import java.awt.dnd.DragSource;
25 import java.awt.event.KeyAdapter;
26 import java.awt.event.KeyEvent;
27 import java.awt.event.MouseAdapter;
28 import java.awt.event.MouseEvent;
29 import java.beans.PropertyChangeEvent;
30 import java.beans.PropertyChangeListener;
31 import java.util.Arrays;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import javax.swing.BorderFactory;
36 import javax.swing.Box;
37 import javax.swing.BoxLayout;
38 import javax.swing.JComponent;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JProgressBar;
42
43 import com.eviware.soapui.impl.wsdl.WsdlProject;
44 import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
45 import com.eviware.soapui.impl.wsdl.actions.project.AddNewTestSuiteAction;
46 import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarTestSuiteAdapter;
47 import com.eviware.soapui.model.ModelItem;
48 import com.eviware.soapui.model.support.ProjectListenerAdapter;
49 import com.eviware.soapui.model.testsuite.TestSuite;
50 import com.eviware.soapui.support.UISupport;
51 import com.eviware.soapui.support.action.swing.ActionList;
52 import com.eviware.soapui.support.action.swing.ActionListBuilder;
53 import com.eviware.soapui.support.action.swing.ActionSupport;
54 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
55 import com.eviware.soapui.support.dnd.DropType;
56 import com.eviware.soapui.support.dnd.SoapUIDragAndDropHandler;
57 import com.eviware.soapui.support.dnd.SoapUIDragAndDropable;
58 import com.eviware.soapui.support.swing.AutoscrollSupport;
59
60 /***
61 * A panel showing a scrollable list of TestSuites in a Project.
62 *
63 * @author Ole.Matzura
64 */
65
66 public class JProjectTestSuiteList extends JPanel
67 {
68 private Map<TestSuite, TestSuiteListPanel> panels = new HashMap<TestSuite, TestSuiteListPanel>();
69 private final WsdlProject project;
70 private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
71 private TestSuiteListPanel selectedTestSuite;
72
73 public JProjectTestSuiteList( WsdlProject testSuite )
74 {
75 this.project = testSuite;
76 setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) );
77
78 for( int c = 0; c < testSuite.getTestSuiteCount(); c++ )
79 {
80 TestSuiteListPanel testSuiteListPanel = createTestSuiteListPanel( testSuite.getTestSuiteAt( c ) );
81 panels.put( testSuite.getTestSuiteAt( c ), testSuiteListPanel );
82 add( testSuiteListPanel );
83 }
84
85 add( Box.createVerticalGlue() );
86 setBackground( Color.WHITE );
87
88 testSuite.addProjectListener( testSuiteListener );
89
90 ActionList actions = ActionListBuilder.buildActions( testSuite );
91 actions.removeAction( 0 );
92 actions.removeAction( 0 );
93 setComponentPopupMenu( ActionSupport.buildPopup( actions ) );
94
95 DragSource dragSource = DragSource.getDefaultDragSource();
96
97 SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler( new TestSuiteListDragAndDropable(
98 this ), DropType.AFTER );
99
100 dragSource.createDefaultDragGestureRecognizer( this, DnDConstants.ACTION_COPY_OR_MOVE, dragAndDropHandler );
101 }
102
103 public void reset()
104 {
105 for( TestSuiteListPanel testSuitePanel : panels.values() )
106 {
107 testSuitePanel.reset();
108 }
109 }
110
111 @Override
112 public void addNotify()
113 {
114 super.addNotify();
115 project.addProjectListener( testSuiteListener );
116 }
117
118 @Override
119 public void removeNotify()
120 {
121 super.removeNotify();
122 project.removeProjectListener( testSuiteListener );
123 }
124
125 private final class InternalTestSuiteListener extends ProjectListenerAdapter
126 {
127 public void testSuiteAdded( TestSuite testSuite )
128 {
129 TestSuiteListPanel testSuiteListPanel = createTestSuiteListPanel( testSuite );
130 panels.put( testSuite, testSuiteListPanel );
131 add( testSuiteListPanel, testSuite.getProject().getIndexOfTestSuite( testSuite ) );
132 revalidate();
133 repaint();
134 }
135
136 public void testSuiteRemoved( TestSuite testSuite )
137 {
138 TestSuiteListPanel testSuiteListPanel = panels.get( testSuite );
139 if( testSuiteListPanel != null )
140 {
141 remove( testSuiteListPanel );
142 panels.remove( testSuite );
143 revalidate();
144 repaint();
145 }
146 }
147
148 public void testSuiteMoved( TestSuite testSuite, int index, int offset )
149 {
150 TestSuiteListPanel testSuiteListPanel = panels.get( testSuite );
151 if( testSuiteListPanel != null )
152 {
153 boolean hadFocus = testSuiteListPanel.hasFocus();
154
155 remove( testSuiteListPanel );
156 add( testSuiteListPanel, index + offset );
157
158 revalidate();
159 repaint();
160
161 if( hadFocus )
162 testSuiteListPanel.requestFocus();
163 }
164 }
165 }
166
167 public final class TestSuiteListPanel extends JPanel implements Autoscroll
168 {
169 private final WsdlTestSuite testSuite;
170 private JProgressBar progressBar;
171 private JLabel label;
172 private ProgressBarTestSuiteAdapter progressBarAdapter;
173 private TestSuitePropertyChangeListener testSuitePropertyChangeListener;
174 private AutoscrollSupport autoscrollSupport;
175
176 public TestSuiteListPanel( WsdlTestSuite testSuite )
177 {
178 super( new BorderLayout() );
179
180 setFocusable( true );
181
182 this.testSuite = testSuite;
183 autoscrollSupport = new AutoscrollSupport( this );
184
185 progressBar = new JProgressBar( 0, 100 )
186 {
187 protected void processMouseEvent( MouseEvent e )
188 {
189 if( e.getID() == MouseEvent.MOUSE_PRESSED || e.getID() == MouseEvent.MOUSE_RELEASED )
190 {
191 TestSuiteListPanel.this.processMouseEvent( translateMouseEvent( e ) );
192 }
193 }
194
195 protected void processMouseMotionEvent( MouseEvent e )
196 {
197 TestSuiteListPanel.this.processMouseMotionEvent( translateMouseEvent( e ) );
198 }
199
200 /***
201 * Translates the given mouse event to the enclosing map panel's
202 * coordinate space.
203 */
204 private MouseEvent translateMouseEvent( MouseEvent e )
205 {
206 return new MouseEvent( TestSuiteListPanel.this, e.getID(), e.getWhen(), e.getModifiers(), e.getX()
207 + getX(), e.getY() + getY(), e.getClickCount(), e.isPopupTrigger(), e.getButton() );
208 }
209 };
210
211 JPanel progressPanel = UISupport.createProgressBarPanel( progressBar, 5, false );
212
213 progressBar.setMinimumSize( new Dimension( 0, 10 ) );
214 progressBar.setBackground( Color.WHITE );
215 progressBar.setInheritsPopupMenu( true );
216
217 label = new JLabel( testSuite.getLabel() );
218 label.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
219 label.setInheritsPopupMenu( true );
220 label.setEnabled( !testSuite.isDisabled() );
221
222 add( progressPanel, BorderLayout.CENTER );
223 add( label, BorderLayout.NORTH );
224
225 testSuitePropertyChangeListener = new TestSuitePropertyChangeListener();
226
227 initPopup( testSuite );
228
229 addMouseListener( new MouseAdapter()
230 {
231
232 @Override
233 public void mousePressed( MouseEvent e )
234 {
235 requestFocus();
236 }
237
238 public void mouseClicked( MouseEvent e )
239 {
240 if( e.getClickCount() < 2 )
241 {
242 if( selectedTestSuite != null )
243 selectedTestSuite.setSelected( false );
244
245 setSelected( true );
246 selectedTestSuite = TestSuiteListPanel.this;
247 return;
248 }
249
250 UISupport.selectAndShow( TestSuiteListPanel.this.testSuite );
251 }
252 } );
253
254 addKeyListener( new TestSuiteListPanelKeyHandler() );
255
256
257 setSelected( false );
258 }
259
260 public void reset()
261 {
262 progressBar.setValue( 0 );
263 progressBar.setString( "" );
264 }
265
266 private void initPopup( WsdlTestSuite testSuite )
267 {
268 ActionList actions = ActionListBuilder.buildActions( testSuite );
269 actions.insertAction( SwingActionDelegate.createDelegate( AddNewTestSuiteAction.SOAPUI_ACTION_ID, project,
270 null, null ), 0 );
271 actions.insertAction( ActionSupport.SEPARATOR_ACTION, 1 );
272
273 setComponentPopupMenu( ActionSupport.buildPopup( actions ) );
274 }
275
276 public void addNotify()
277 {
278 super.addNotify();
279 testSuite.addPropertyChangeListener( testSuitePropertyChangeListener );
280 progressBarAdapter = new ProgressBarTestSuiteAdapter( progressBar, testSuite );
281 }
282
283 public void removeNotify()
284 {
285 super.removeNotify();
286 if( progressBarAdapter != null )
287 {
288 testSuite.removePropertyChangeListener( testSuitePropertyChangeListener );
289 progressBarAdapter.release();
290
291 progressBarAdapter = null;
292 }
293 }
294
295 public Dimension getMaximumSize()
296 {
297 Dimension size = super.getMaximumSize();
298 size.height = 50;
299 return size;
300 }
301
302 public void setSelected( boolean selected )
303 {
304 if( selected )
305 {
306 setBorder( BorderFactory.createLineBorder( Color.GRAY ) );
307 }
308 else
309 {
310 setBorder( BorderFactory.createLineBorder( Color.WHITE ) );
311 }
312 }
313
314 public boolean isSelected()
315 {
316 return selectedTestSuite != null && selectedTestSuite.getTestSuite() == testSuite;
317 }
318
319 private final class TestSuitePropertyChangeListener implements PropertyChangeListener
320 {
321 public void propertyChange( PropertyChangeEvent evt )
322 {
323 if( evt.getPropertyName().equals( TestSuite.LABEL_PROPERTY ) )
324 {
325 label.setEnabled( !testSuite.isDisabled() );
326 label.setText( testSuite.getLabel() );
327 }
328 else if( evt.getPropertyName().equals( TestSuite.DISABLED_PROPERTY ) )
329 {
330 initPopup( testSuite );
331 }
332 }
333 }
334
335 protected WsdlTestSuite getTestSuite()
336 {
337 return testSuite;
338 }
339
340 public ModelItem getModelItem()
341 {
342 return testSuite;
343 }
344
345 public void autoscroll( Point pt )
346 {
347 int ix = getIndexOf( this );
348 if( pt.getY() < 12 && ix > 0 )
349 {
350 Rectangle bounds = JProjectTestSuiteList.this.getComponent( ix - 1 ).getBounds();
351 JProjectTestSuiteList.this.scrollRectToVisible( bounds );
352 }
353 else if( pt.getY() > getHeight() - 12 && ix < project.getTestSuiteCount() - 1 )
354 {
355 Rectangle bounds = JProjectTestSuiteList.this.getComponent( ix + 1 ).getBounds();
356 JProjectTestSuiteList.this.scrollRectToVisible( bounds );
357 }
358 }
359
360 public Insets getAutoscrollInsets()
361 {
362 return autoscrollSupport.getAutoscrollInsets();
363 }
364
365 private final class TestSuiteListPanelKeyHandler extends KeyAdapter
366 {
367 public void keyPressed( KeyEvent e )
368 {
369 if( e.getKeyChar() == KeyEvent.VK_ENTER )
370 {
371 UISupport.selectAndShow( testSuite );
372 e.consume();
373 }
374 else
375 {
376 ActionList actions = ActionListBuilder.buildActions( testSuite );
377 if( actions != null )
378 actions.dispatchKeyEvent( e );
379 }
380 }
381 }
382 }
383
384 protected int getIndexOf( TestSuiteListPanel panel )
385 {
386 return Arrays.asList( getComponents() ).indexOf( panel );
387 }
388
389 protected TestSuiteListPanel createTestSuiteListPanel( TestSuite testSuite )
390 {
391 TestSuiteListPanel testSuiteListPanel = new TestSuiteListPanel( ( WsdlTestSuite )testSuite );
392
393 DragSource dragSource = DragSource.getDefaultDragSource();
394
395 SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler(
396 new TestSuiteListPanelDragAndDropable( testSuiteListPanel ), DropType.BEFORE_AND_AFTER );
397
398 dragSource.createDefaultDragGestureRecognizer( testSuiteListPanel, DnDConstants.ACTION_COPY_OR_MOVE,
399 dragAndDropHandler );
400
401 return testSuiteListPanel;
402 }
403
404 private class TestSuiteListDragAndDropable implements SoapUIDragAndDropable<ModelItem>
405 {
406 private final JProjectTestSuiteList list;
407
408 public TestSuiteListDragAndDropable( JProjectTestSuiteList list )
409 {
410 this.list = list;
411 }
412
413 public JComponent getComponent()
414 {
415 return list;
416 }
417
418 public Rectangle getModelItemBounds( ModelItem modelItem )
419 {
420 return list.getBounds();
421 }
422
423 public ModelItem getModelItemForLocation( int x, int y )
424 {
425 int testSuiteCount = project.getTestSuiteCount();
426 return testSuiteCount == 0 ? project : project.getTestSuiteAt( testSuiteCount - 1 );
427 }
428
429 public Component getRenderer( ModelItem modelItem )
430 {
431 return null;
432 }
433
434 public void selectModelItem( ModelItem modelItem )
435 {
436 }
437
438 public void setDragInfo( String dropInfo )
439 {
440 list.setToolTipText( dropInfo );
441 }
442
443 public void toggleExpansion( ModelItem modelItem )
444 {
445 }
446 }
447
448 private static class TestSuiteListPanelDragAndDropable implements SoapUIDragAndDropable<ModelItem>
449 {
450 private final TestSuiteListPanel testSuitePanel;
451
452 public TestSuiteListPanelDragAndDropable( TestSuiteListPanel testSuitePanel )
453 {
454 this.testSuitePanel = testSuitePanel;
455 }
456
457 public JComponent getComponent()
458 {
459 return testSuitePanel;
460 }
461
462 public void setDragInfo( String dropInfo )
463 {
464 testSuitePanel.setToolTipText( dropInfo.length() == 0 ? null : dropInfo );
465 }
466
467 public Rectangle getModelItemBounds( ModelItem path )
468 {
469 return new Rectangle( testSuitePanel.getSize() );
470 }
471
472 public ModelItem getModelItemForLocation( int x, int y )
473 {
474 return testSuitePanel.getModelItem();
475 }
476
477 public Component getRenderer( ModelItem path )
478 {
479 return null;
480 }
481
482 public void selectModelItem( ModelItem path )
483 {
484 testSuitePanel.setSelected( !testSuitePanel.isSelected() );
485 }
486
487 public void toggleExpansion( ModelItem last )
488 {
489 }
490 }
491 }