View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui;
14  
15  import java.awt.event.ActionEvent;
16  import java.lang.ref.Reference;
17  import java.lang.ref.WeakReference;
18  import java.util.Iterator;
19  
20  import javax.swing.AbstractAction;
21  import javax.swing.Action;
22  import javax.swing.JMenu;
23  import javax.swing.JMenuItem;
24  import javax.swing.event.PopupMenuEvent;
25  import javax.swing.event.PopupMenuListener;
26  
27  import com.eviware.soapui.impl.WorkspaceImpl;
28  import com.eviware.soapui.impl.actions.ImportWsdlProjectAction;
29  import com.eviware.soapui.impl.actions.SwitchWorkspaceAction;
30  import com.eviware.soapui.impl.wsdl.WsdlProject;
31  import com.eviware.soapui.model.ModelItem;
32  import com.eviware.soapui.model.iface.Interface;
33  import com.eviware.soapui.model.iface.Operation;
34  import com.eviware.soapui.model.iface.Request;
35  import com.eviware.soapui.model.mock.MockOperation;
36  import com.eviware.soapui.model.mock.MockResponse;
37  import com.eviware.soapui.model.mock.MockService;
38  import com.eviware.soapui.model.project.Project;
39  import com.eviware.soapui.model.support.WorkspaceListenerAdapter;
40  import com.eviware.soapui.model.testsuite.LoadTest;
41  import com.eviware.soapui.model.testsuite.TestCase;
42  import com.eviware.soapui.model.testsuite.TestStep;
43  import com.eviware.soapui.model.testsuite.TestSuite;
44  import com.eviware.soapui.model.workspace.Workspace;
45  import com.eviware.soapui.model.workspace.WorkspaceListener;
46  import com.eviware.soapui.support.UISupport;
47  import com.eviware.soapui.support.action.SoapUIActionMapping;
48  import com.eviware.soapui.support.action.support.DefaultActionMapping;
49  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
50  import com.eviware.soapui.support.types.StringToStringMap;
51  import com.eviware.soapui.ui.desktop.DesktopListener;
52  import com.eviware.soapui.ui.desktop.DesktopPanel;
53  
54  /***
55   * Workspace/Deskopt Listener that updates the recent menus..
56   * 
57   * @author ole.matzura
58   */
59  
60  public class RecentItemsListener extends WorkspaceListenerAdapter implements WorkspaceListener, DesktopListener
61  {
62  	private static final String RECENT_WORKSPACES_SETTING = "RecentWorkspaces";
63  	private static final String RECENT_PROJECTS_SETTING = "RecentProjects";
64  	private static final String EMPTYMARKER = "- empty -";
65  	private static final String CLEAR_ITEMS = "Clear Items";
66  	private JMenu recentProjectsMenu;
67  	private JMenu recentWorkspacesMenu;
68  	private JMenu recentEditorsMenu;
69  	private boolean switchingWorkspace;
70  
71  	public RecentItemsListener( JMenu recentWorkspacesMenu2, JMenu recentProjectsMenu2, JMenu recentEditorsMenu2 )
72  	{
73  		recentWorkspacesMenu = recentWorkspacesMenu2;
74  		recentProjectsMenu = recentProjectsMenu2;
75  		recentEditorsMenu = recentEditorsMenu2;
76  		recentEditorsMenu.add( EMPTYMARKER ).setEnabled( false );
77  		recentEditorsMenu.getPopupMenu().addPopupMenuListener( new PopupMenuListener()
78  		{
79  
80  			public void popupMenuCanceled( PopupMenuEvent e )
81  			{
82  			}
83  
84  			public void popupMenuWillBecomeInvisible( PopupMenuEvent e )
85  			{
86  			}
87  
88  			public void popupMenuWillBecomeVisible( PopupMenuEvent e )
89  			{
90  				int editorCount = 0;
91  				for( int c = 0; c < recentEditorsMenu.getItemCount(); c++ )
92  				{
93  					ShowEditorAction action = getShowEditorAction( recentEditorsMenu, c );
94  					if( action == null )
95  						continue;
96  
97  					editorCount++ ;
98  
99  					if( action.isReleased() )
100 					{
101 						recentEditorsMenu.remove( c );
102 						c-- ;
103 					}
104 					else
105 					{
106 						try
107 						{
108 							action.update();
109 						}
110 						catch( Throwable e1 )
111 						{
112 							recentEditorsMenu.remove( c );
113 							c-- ;
114 						}
115 					}
116 				}
117 
118 				// Look for a Clear Items JMenuItem, and create it if not existing
119 				JMenuItem clearAllItem = null;
120 				for( int i = 0; i < recentEditorsMenu.getItemCount(); ++i )
121 				{
122 					JMenuItem editorItem = recentEditorsMenu.getItem( i );
123 					if( editorItem == null )
124 						continue;
125 
126 					if( editorItem.getText().equals( CLEAR_ITEMS ) )
127 						clearAllItem = editorItem;
128 				}
129 				if( clearAllItem == null )
130 				{
131 					clearAllItem = new JMenuItem( new ClearEditorsAction() );
132 					recentEditorsMenu.addSeparator();
133 					recentEditorsMenu.add( clearAllItem );
134 				}
135 
136 				clearAllItem.setEnabled( editorCount > 0 );
137 
138 				// Create Empty Marker if needed.
139 				if( editorCount == 0 && recentEditorsMenu.getItemCount() <= 2 )
140 					recentEditorsMenu.add( new JMenuItem( EMPTYMARKER ), 0 ).setEnabled( false );
141 
142 			}
143 		} );
144 
145 		updateRecentWorkspacesMenu();
146 		updateRecentProjectsMenu();
147 	}
148 
149 	@SuppressWarnings( "unchecked" )
150 	private void updateRecentWorkspacesMenu()
151 	{
152 		String recent = SoapUI.getSettings().getString( RECENT_WORKSPACES_SETTING, null );
153 		StringToStringMap history = recent == null ? new StringToStringMap() : StringToStringMap.fromXml( recent );
154 
155 		recentWorkspacesMenu.removeAll();
156 
157 		if( history.size() > 0 )
158 		{
159 			for( Iterator<String> i = history.keySet().iterator(); i.hasNext(); )
160 			{
161 				String filePath = i.next();
162 				DefaultActionMapping<WorkspaceImpl> mapping = new DefaultActionMapping<WorkspaceImpl>(
163 						SwitchWorkspaceAction.SOAPUI_ACTION_ID, null, null, false, filePath );
164 				String wsName = history.get( filePath );
165 
166 				if( SoapUI.getWorkspace().getPath().equals( filePath ) )
167 					continue;
168 
169 				mapping.setName( wsName );
170 				mapping.setDescription( "Switches to the [" + wsName + "] workspace" );
171 
172 				AbstractAction delegate = new SwingActionDelegate( mapping, SoapUI.getWorkspace() );
173 				recentWorkspacesMenu.add( new JMenuItem( delegate ) );
174 			}
175 		}
176 		else
177 		{
178 			recentWorkspacesMenu.add( EMPTYMARKER ).setEnabled( false );
179 		}
180 
181 		recentWorkspacesMenu.addSeparator();
182 		recentWorkspacesMenu.add( new ClearWorkspacesAction() ).setEnabled( history.size() > 0 );
183 	}
184 
185 	@SuppressWarnings( "unchecked" )
186 	private void updateRecentProjectsMenu()
187 	{
188 		recentProjectsMenu.removeAll();
189 
190 		String recent = SoapUI.getSettings().getString( RECENT_PROJECTS_SETTING, null );
191 		StringToStringMap history = recent == null ? new StringToStringMap() : StringToStringMap.fromXml( recent );
192 
193 		if( history.size() > 0 )
194 		{
195 			for( Iterator<String> i = history.keySet().iterator(); i.hasNext(); )
196 			{
197 				String filePath = i.next();
198 				DefaultActionMapping<WorkspaceImpl> mapping = new DefaultActionMapping<WorkspaceImpl>(
199 						ImportWsdlProjectAction.SOAPUI_ACTION_ID, null, null, false, filePath );
200 				String wsName = history.get( filePath );
201 				mapping.setName( wsName );
202 				mapping.setDescription( "Switches to the [" + wsName + "] project" );
203 
204 				AbstractAction delegate = new SwingActionDelegate( mapping, SoapUI.getWorkspace() );
205 				recentProjectsMenu.add( new JMenuItem( delegate ) );
206 			}
207 		}
208 		else
209 		{
210 			recentProjectsMenu.add( EMPTYMARKER ).setEnabled( false );
211 		}
212 
213 		recentProjectsMenu.addSeparator();
214 		recentProjectsMenu.add( new ClearProjectsAction() ).setEnabled( history.size() > 0 );
215 	}
216 
217 	@SuppressWarnings( "unchecked" )
218 	public void projectAdded( Project project )
219 	{
220 		if( switchingWorkspace )
221 			return;
222 
223 		String filePath = ( ( WsdlProject )project ).getPath();
224 		if( filePath == null )
225 			return;
226 
227 		String recent = SoapUI.getSettings().getString( RECENT_PROJECTS_SETTING, null );
228 		if( recent != null )
229 		{
230 			StringToStringMap history = StringToStringMap.fromXml( recent );
231 			history.remove( filePath );
232 			SoapUI.getSettings().setString( RECENT_PROJECTS_SETTING, history.toXml() );
233 		}
234 
235 		for( int c = 0; c < recentProjectsMenu.getItemCount() - 2; c++ )
236 		{
237 			JMenuItem item = recentProjectsMenu.getItem( c );
238 			if( item == null )
239 				continue;
240 
241 			Action action = item.getAction();
242 			if( !( action instanceof SwingActionDelegate ) )
243 				continue;
244 
245 			SwingActionDelegate actionDelegate = ( SwingActionDelegate )action;
246 			if( actionDelegate == null )
247 				continue;
248 
249 			SoapUIActionMapping mapping = actionDelegate.getMapping();
250 			if( filePath.equals( mapping.getParam() ) )
251 			{
252 				recentProjectsMenu.remove( c );
253 				break;
254 			}
255 		}
256 
257 		if( recentProjectsMenu.getItemCount() == 2 )
258 		{
259 			recentProjectsMenu.add( new JMenuItem( EMPTYMARKER ), 0 ).setEnabled( false );
260 			recentProjectsMenu.getItem( recentProjectsMenu.getItemCount() - 1 ).setEnabled( false );
261 		}
262 	}
263 
264 	public void projectChanged( Project project )
265 	{
266 	}
267 
268 	@SuppressWarnings( "unchecked" )
269 	public void projectRemoved( Project project )
270 	{
271 		if( switchingWorkspace )
272 			return;
273 
274 		String filePath = ( ( WsdlProject )project ).getPath();
275 
276 		String recent = SoapUI.getSettings().getString( RECENT_PROJECTS_SETTING, null );
277 		StringToStringMap history = recent == null ? new StringToStringMap() : StringToStringMap.fromXml( recent );
278 		history.put( filePath, project.getName() );
279 		SoapUI.getSettings().setString( RECENT_PROJECTS_SETTING, history.toXml() );
280 
281 		DefaultActionMapping<WorkspaceImpl> mapping = new DefaultActionMapping<WorkspaceImpl>(
282 				ImportWsdlProjectAction.SOAPUI_ACTION_ID, null, null, false, filePath );
283 		mapping.setName( project.getName() );
284 		mapping.setDescription( "Switches to the [" + project.getName() + "] project" );
285 
286 		AbstractAction delegate = new SwingActionDelegate( mapping, SoapUI.getWorkspace() );
287 
288 		recentProjectsMenu.add( new JMenuItem( delegate ), recentProjectsMenu.getItemCount() - 2 );
289 
290 		recentProjectsMenu.getItem( recentProjectsMenu.getItemCount() - 1 ).setEnabled( true );
291 
292 		if( isEmptyMarker( recentProjectsMenu.getItem( 0 ) ) )
293 			recentProjectsMenu.remove( 0 );
294 
295 		removeProjectEditors( project );
296 
297 	}
298 
299 	private void removeProjectEditors( Project project )
300 	{
301 		for( int c = 0; c < recentEditorsMenu.getItemCount(); c++ )
302 		{
303 			ShowEditorAction action = getShowEditorAction( recentEditorsMenu, c );
304 			if( action == null )
305 				continue;
306 
307 			if( action.isReleased() )
308 			{
309 				recentEditorsMenu.remove( c );
310 				c-- ;
311 			}
312 			else
313 			{
314 				try
315 				{
316 					action.update();
317 					if( dependsOnProject( action.getModelItem(), project ) )
318 					{
319 						recentEditorsMenu.remove( c );
320 						c-- ;
321 					}
322 				}
323 				catch( Throwable e1 )
324 				{
325 					recentEditorsMenu.remove( c );
326 					c-- ;
327 				}
328 			}
329 		}
330 	}
331 
332 	private boolean dependsOnProject( ModelItem modelItem, Project project )
333 	{
334 		if( modelItem instanceof Interface )
335 		{
336 			return ( ( Interface )modelItem ).getProject() == project;
337 		}
338 		else if( modelItem instanceof Operation )
339 		{
340 			return ( ( Operation )modelItem ).getInterface().getProject() == project;
341 		}
342 		else if( modelItem instanceof Request )
343 		{
344 			return ( ( Request )modelItem ).getOperation().getInterface().getProject() == project;
345 		}
346 		else if( modelItem instanceof TestSuite )
347 		{
348 			return ( ( TestSuite )modelItem ).getProject() == project;
349 		}
350 		else if( modelItem instanceof TestCase )
351 		{
352 			return ( ( TestCase )modelItem ).getTestSuite().getProject() == project;
353 		}
354 		else if( modelItem instanceof TestStep )
355 		{
356 			return ( ( TestStep )modelItem ).getTestCase().getTestSuite().getProject() == project;
357 		}
358 		else if( modelItem instanceof LoadTest )
359 		{
360 			return ( ( LoadTest )modelItem ).getTestCase().getTestSuite().getProject() == project;
361 		}
362 		else if( modelItem instanceof MockService )
363 		{
364 			return ( ( MockService )modelItem ).getProject() == project;
365 		}
366 		else if( modelItem instanceof MockOperation )
367 		{
368 			return ( ( MockOperation )modelItem ).getMockService().getProject() == project;
369 		}
370 		else if( modelItem instanceof MockResponse )
371 		{
372 			return ( ( MockResponse )modelItem ).getMockOperation().getMockService().getProject() == project;
373 		}
374 
375 		return false;
376 	}
377 
378 	@SuppressWarnings( "unchecked" )
379 	public void workspaceSwitched( Workspace workspace )
380 	{
381 		switchingWorkspace = false;
382 
383 		String filePath = workspace.getPath();
384 
385 		String recent = SoapUI.getSettings().getString( RECENT_WORKSPACES_SETTING, null );
386 		if( recent != null )
387 		{
388 			StringToStringMap history = StringToStringMap.fromXml( recent );
389 			history.remove( filePath );
390 			SoapUI.getSettings().setString( RECENT_WORKSPACES_SETTING, history.toXml() );
391 		}
392 
393 		for( int c = 0; c < recentWorkspacesMenu.getItemCount(); c++ )
394 		{
395 			JMenuItem item = recentWorkspacesMenu.getItem( c );
396 			if( item == null )
397 				continue;
398 
399 			Action action = item.getAction();
400 			if( !( action instanceof SwingActionDelegate ) )
401 				continue;
402 
403 			SwingActionDelegate actionDelegate = ( SwingActionDelegate )action;
404 			if( actionDelegate == null )
405 				continue;
406 
407 			SoapUIActionMapping mapping = actionDelegate.getMapping();
408 			if( filePath.equals( mapping.getParam() ) )
409 			{
410 				recentWorkspacesMenu.remove( c );
411 				break;
412 			}
413 		}
414 
415 		if( recentWorkspacesMenu.getItemCount() == 2 )
416 			recentWorkspacesMenu.add( new JMenuItem( EMPTYMARKER ), 0 ).setEnabled( false );
417 	}
418 
419 	@SuppressWarnings( "unchecked" )
420 	public void workspaceSwitching( Workspace workspace )
421 	{
422 		switchingWorkspace = true;
423 		recentEditorsMenu.removeAll();
424 		if( recentEditorsMenu.getItemCount() == 0 )
425 			recentEditorsMenu.add( EMPTYMARKER ).setEnabled( false );
426 
427 		String filePath = workspace.getPath();
428 		DefaultActionMapping<WorkspaceImpl> mapping = new DefaultActionMapping<WorkspaceImpl>(
429 				SwitchWorkspaceAction.SOAPUI_ACTION_ID, null, null, false, filePath );
430 		mapping.setName( workspace.getName() );
431 		mapping.setDescription( "Switches to the [" + workspace.getName() + "] workspace" );
432 
433 		AbstractAction delegate = new SwingActionDelegate( mapping, SoapUI.getWorkspace() );
434 		recentWorkspacesMenu.add( new JMenuItem( delegate ), recentWorkspacesMenu.getItemCount() - 2 );
435 
436 		recentWorkspacesMenu.getItem( recentWorkspacesMenu.getItemCount() - 1 ).setEnabled( true );
437 		System.out.println( recentWorkspacesMenu.getItem( recentWorkspacesMenu.getItemCount() - 1 ).getText() );
438 
439 		String recent = SoapUI.getSettings().getString( RECENT_WORKSPACES_SETTING, null );
440 		StringToStringMap history = recent == null ? new StringToStringMap() : StringToStringMap.fromXml( recent );
441 		history.put( filePath, workspace.getName() );
442 		SoapUI.getSettings().setString( RECENT_WORKSPACES_SETTING, history.toXml() );
443 
444 		if( isEmptyMarker( recentWorkspacesMenu.getItem( 0 ) ) )
445 			recentWorkspacesMenu.remove( 0 );
446 
447 		recentEditorsMenu.removeAll();
448 	}
449 
450 	public void desktopPanelClosed( DesktopPanel desktopPanel )
451 	{
452 		ModelItem modelItem = desktopPanel.getModelItem();
453 		if( modelItem == null || recentEditorsMenu.getItemCount() == 0 )
454 			return;
455 
456 		if( isEmptyMarker( recentEditorsMenu.getItem( 0 ) ) )
457 			recentEditorsMenu.remove( 0 );
458 
459 		recentEditorsMenu.add( new JMenuItem( new ShowEditorAction( modelItem ) ), 0 );
460 	}
461 
462 	public void desktopPanelCreated( DesktopPanel desktopPanel )
463 	{
464 		for( int c = 0; c < recentEditorsMenu.getItemCount(); c++ )
465 		{
466 			ShowEditorAction action = getShowEditorAction( recentEditorsMenu, c );
467 			if( action == null )
468 				continue;
469 
470 			if( action.isReleased() )
471 			{
472 				recentEditorsMenu.remove( c );
473 				c-- ;
474 			}
475 			else if( action.getModelItem().equals( desktopPanel.getModelItem() ) )
476 			{
477 				recentEditorsMenu.remove( c );
478 				break;
479 			}
480 		}
481 
482 		if( recentEditorsMenu.getItemCount() == 2 )
483 			recentEditorsMenu.add( new JMenuItem( EMPTYMARKER ), 0 ).setEnabled( false );
484 	}
485 
486 	public void desktopPanelSelected( DesktopPanel desktopPanel )
487 	{
488 	}
489 
490 	private static class ShowEditorAction extends AbstractAction
491 	{
492 		private Reference<ModelItem> ref;
493 
494 		public ShowEditorAction( ModelItem modelItem )
495 		{
496 			super( modelItem.getName() );
497 
498 			putValue( Action.SHORT_DESCRIPTION, "Reopen editor for [" + modelItem.getName() + "]" );
499 			ref = new WeakReference<ModelItem>( modelItem );
500 		}
501 
502 		public ModelItem getModelItem()
503 		{
504 			return ref.get();
505 		}
506 
507 		public void update()
508 		{
509 			ModelItem modelItem = ref.get();
510 			if( modelItem == null )
511 				return;
512 
513 			putValue( Action.NAME, modelItem.getName() );
514 			putValue( Action.SHORT_DESCRIPTION, "Reopen editor for [" + modelItem.getName() + "]" );
515 		}
516 
517 		public boolean isReleased()
518 		{
519 			return ref.get() == null;
520 		}
521 
522 		public void actionPerformed( ActionEvent e )
523 		{
524 			ModelItem modelItem = ref.get();
525 			if( modelItem != null )
526 				UISupport.showDesktopPanel( modelItem );
527 			else
528 				UISupport.showErrorMessage( "Item [" + getValue( Action.NAME ) + "] is no longer available" );
529 		}
530 	}
531 
532 	/* Helper methods */
533 
534 	/***
535 	 * Confirms that the item of index i in menu is a ShowEditorAction, and
536 	 * extracts the ShowEditorAction.
537 	 * 
538 	 * @param menu
539 	 *           The menu to get the JMenuItem, containing the action from.
540 	 * @param i
541 	 *           The index where the JMenuItem is located in menu.
542 	 * @return The ShowEditorAction if confirmed. Otherwise null.
543 	 */
544 	private ShowEditorAction getShowEditorAction( JMenu menu, int i )
545 	{
546 		JMenuItem menuItem = recentEditorsMenu.getItem( i );
547 		if( menuItem == null )
548 			return null;
549 
550 		Action unknownAction = menuItem.getAction();
551 
552 		if( unknownAction == null || !( unknownAction instanceof ShowEditorAction ) )
553 			return null;
554 
555 		return ( ShowEditorAction )unknownAction;
556 	}
557 
558 	/***
559 	 * Checks whether a JMenuItem is an Empty marker (marking an empty list).
560 	 * 
561 	 * @param item
562 	 *           The item to check.
563 	 * @return True if item is an Empty marker. False otherwise (including if
564 	 *         item is null).
565 	 */
566 	private boolean isEmptyMarker( JMenuItem item )
567 	{
568 		if( item == null )
569 			return false;
570 		if( item.getText().equals( EMPTYMARKER ) )
571 			return true;
572 		return false;
573 	}
574 
575 	/*
576 	 * Action classes for clearing all items in the Recent
577 	 * Editors/Projects/Workspaces submenu
578 	 */
579 
580 	@SuppressWarnings( "serial" )
581 	private class ClearProjectsAction extends AbstractAction
582 	{
583 		public ClearProjectsAction()
584 		{
585 			super( CLEAR_ITEMS );
586 			putValue( Action.SHORT_DESCRIPTION, "Clear all recent projects" );
587 		}
588 
589 		public void actionPerformed( ActionEvent e )
590 		{
591 			if( !UISupport.confirm( "Remove all Projects from this menu?", "Question" ) )
592 				return;
593 
594 			StringToStringMap emptyMap = new StringToStringMap();
595 
596 			SoapUI.getSettings().setString( RECENT_PROJECTS_SETTING, emptyMap.toXml() );
597 			updateRecentProjectsMenu();
598 
599 		}
600 	}
601 
602 	@SuppressWarnings( "serial" )
603 	private class ClearWorkspacesAction extends AbstractAction
604 	{
605 		public ClearWorkspacesAction()
606 		{
607 			super( CLEAR_ITEMS );
608 			putValue( Action.SHORT_DESCRIPTION, "Clear all recent workspaces" );
609 		}
610 
611 		public void actionPerformed( ActionEvent e )
612 		{
613 			if( !UISupport.confirm( "Remove all Workspaces from this menu?", "Question" ) )
614 				return;
615 
616 			StringToStringMap emptyMap = new StringToStringMap();
617 
618 			SoapUI.getSettings().setString( RECENT_WORKSPACES_SETTING, emptyMap.toXml() );
619 			updateRecentWorkspacesMenu();
620 
621 		}
622 	}
623 
624 	@SuppressWarnings( "serial" )
625 	private class ClearEditorsAction extends AbstractAction
626 	{
627 		public ClearEditorsAction()
628 		{
629 			super( CLEAR_ITEMS );
630 			putValue( Action.SHORT_DESCRIPTION, "Clear all recent Editors" );
631 		}
632 
633 		public void actionPerformed( ActionEvent e )
634 		{
635 			if( !UISupport.confirm( "Remove all Editors from this menu?", "Question" ) )
636 				return;
637 
638 			recentEditorsMenu.removeAll();
639 			recentEditorsMenu.add( EMPTYMARKER ).setEnabled( false );
640 			recentEditorsMenu.addSeparator();
641 			recentEditorsMenu.add( new ClearEditorsAction() );
642 		}
643 	}
644 
645 }