KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > ui > actions > ContextualLaunchAction


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.debug.ui.actions;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19
20 import org.eclipse.core.expressions.EvaluationContext;
21 import org.eclipse.core.expressions.Expression;
22 import org.eclipse.core.expressions.IEvaluationContext;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.debug.core.DebugPlugin;
25 import org.eclipse.debug.core.ILaunchConfiguration;
26 import org.eclipse.debug.core.ILaunchManager;
27 import org.eclipse.debug.internal.ui.DebugUIPlugin;
28 import org.eclipse.debug.internal.ui.actions.LaunchConfigurationAction;
29 import org.eclipse.debug.internal.ui.actions.LaunchShortcutAction;
30 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
31 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
32 import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
33 import org.eclipse.debug.ui.DebugUITools;
34 import org.eclipse.debug.ui.ILaunchGroup;
35 import org.eclipse.jface.action.ActionContributionItem;
36 import org.eclipse.jface.action.IAction;
37 import org.eclipse.jface.action.IMenuCreator;
38 import org.eclipse.jface.viewers.ISelection;
39 import org.eclipse.jface.viewers.IStructuredSelection;
40 import org.eclipse.swt.SWT;
41 import org.eclipse.swt.events.MenuAdapter;
42 import org.eclipse.swt.events.MenuEvent;
43 import org.eclipse.swt.widgets.Control;
44 import org.eclipse.swt.widgets.Menu;
45 import org.eclipse.swt.widgets.MenuItem;
46 import org.eclipse.ui.IObjectActionDelegate;
47 import org.eclipse.ui.IWorkbenchPart;
48 import org.eclipse.ui.PlatformUI;
49 import org.eclipse.ui.activities.WorkbenchActivityHelper;
50
51 /**
52  * An action delegate that builds a context menu with applicable launch shortcuts
53  * for a specific launch mode.
54  * <p>
55  * This class can be sub-classed and contributed as an object contribution pop-up
56  * menu extension action. When invoked, it becomes a sub-menu that dynamically
57  * builds a list of applicable launch shortcuts for the current selection.
58  * Each launch shortcut may have optional information to support a context menu action.
59  * </p>
60  * <p>
61  * Clients may subclass this class.
62  * </p>
63  * @since 3.0
64  */

65 public abstract class ContextualLaunchAction implements IObjectActionDelegate, IMenuCreator {
66
67     private IAction fDelegateAction;
68     private String JavaDoc fMode;
69     // default launch group for this mode (null category)
70
private ILaunchGroup fGroup = null;
71     // map of launch groups by (non-null) categories, for this mode
72
private Map JavaDoc fGroupsByCategory = null;
73     // whether to re-fill the menu (reset on selection change)
74
private boolean fFillMenu = true;
75     
76     /**
77      * Constructs a contextual launch action for the given launch mode.
78      *
79      * @param mode launch mode
80      */

81     public ContextualLaunchAction(String JavaDoc mode) {
82         fMode = mode;
83         ILaunchGroup[] groups = DebugUITools.getLaunchGroups();
84         fGroupsByCategory = new HashMap JavaDoc(3);
85         for (int i = 0; i < groups.length; i++) {
86             ILaunchGroup group = groups[i];
87             if (group.getMode().equals(mode)) {
88                 if (group.getCategory() == null) {
89                     fGroup = group;
90                 } else {
91                     fGroupsByCategory.put(group.getCategory(), group);
92                 }
93             }
94         }
95     }
96     
97     /*
98      * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
99      */

100     public void setActivePart(IAction action, IWorkbenchPart targetPart) {
101         // We don't have a need for the active part.
102
}
103     /* (non-Javadoc)
104      * @see org.eclipse.jface.action.IMenuCreator#dispose()
105      */

106     public void dispose() {
107         // nothing to do
108
}
109     /* (non-Javadoc)
110      * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control)
111      */

112     public Menu getMenu(Control parent) {
113         // never called
114
return null;
115     }
116     /* (non-Javadoc)
117      * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu)
118      */

119     public Menu getMenu(Menu parent) {
120         //Create the new menu. The menu will get filled when it is about to be shown. see fillMenu(Menu).
121
Menu menu = new Menu(parent);
122         /**
123          * Add listener to re-populate the menu each time
124          * it is shown because MenuManager.update(boolean, boolean)
125          * doesn't dispose pull-down ActionContribution items for each popup menu.
126          */

127         menu.addMenuListener(new MenuAdapter() {
128             public void menuShown(MenuEvent e) {
129                 if (fFillMenu) {
130                     Menu m = (Menu)e.widget;
131                     MenuItem[] items = m.getItems();
132                     for (int i=0; i < items.length; i++) {
133                         items[i].dispose();
134                     }
135                     fillMenu(m);
136                     fFillMenu = false;
137                 }
138             }
139         });
140         return menu;
141     }
142
143     /*
144      * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
145      */

146     public void run(IAction action) {
147         // Never called because we become a menu.
148
}
149     
150     /*
151      * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
152      */

153     public void selectionChanged(IAction action, ISelection selection) {
154         // if the selection is an IResource, save it and enable our action
155
if (selection instanceof IStructuredSelection) {
156             fFillMenu = true;
157             if (fDelegateAction != action) {
158                 fDelegateAction = action;
159                 fDelegateAction.setMenuCreator(this);
160             }
161             //enable our menu
162
action.setEnabled(true);
163             return;
164         }
165         action.setEnabled(false);
166     }
167     
168     /**
169      * Returns the launch manager
170      * @return the launch manager
171      * @since 3.3
172      */

173     protected ILaunchManager getLaunchManager() {
174         return DebugPlugin.getDefault().getLaunchManager();
175     }
176     
177     /**
178      * Fills the menu with applicable launch shortcuts
179      * @param menu The menu to fill
180      */

181     protected void fillMenu(Menu menu) {
182         IStructuredSelection ss = SelectedResourceManager.getDefault().getCurrentSelection();
183         int accelerator = 1;
184         if(!ss.isEmpty()) {
185             try {
186                 //try to add the shared config it the context is one.
187
ILaunchConfiguration config = getLaunchConfigurationManager().isSharedConfig(ss.getFirstElement());
188                 if(config != null && config.exists() && config.supportsMode(fMode)) {
189                     IAction action = new LaunchConfigurationAction(config, fMode, config.getName(), DebugUITools.getDefaultImageDescriptor(config), accelerator++);
190                     ActionContributionItem item = new ActionContributionItem(action);
191                     item.fill(menu, -1);
192                 }
193             }
194             catch (CoreException ce) {}
195         }
196         
197         List JavaDoc allShortCuts = getLaunchConfigurationManager().getLaunchShortcuts();
198         Iterator JavaDoc iter = allShortCuts.iterator();
199         List JavaDoc filteredShortCuts = new ArrayList JavaDoc(10);
200     
201     //create a context
202
List JavaDoc selection = ss.toList();
203         IEvaluationContext context = new EvaluationContext(null, selection);
204         context.setAllowPluginActivation(true);
205         context.addVariable("selection", selection); //$NON-NLS-1$
206
while (iter.hasNext()) {
207             LaunchShortcutExtension ext = (LaunchShortcutExtension) iter.next();
208             try {
209                 if (!WorkbenchActivityHelper.filterItem(ext) && isApplicable(ext, context)) {
210                     filteredShortCuts.add(ext);
211                 }
212             }
213             catch (CoreException e) {}
214         }
215         iter = filteredShortCuts.iterator();
216     
217     //we need a separator iff the shared config entry has been added and there are following shortcuts
218
if(menu.getItemCount() > 0 && filteredShortCuts.size() > 0) {
219              new MenuItem(menu, SWT.SEPARATOR);
220         }
221         List JavaDoc categories = new ArrayList JavaDoc();
222         while (iter.hasNext()) {
223             LaunchShortcutExtension ext = (LaunchShortcutExtension) iter.next();
224             Set JavaDoc modes = ext.getModes(); // supported launch modes
225
Iterator JavaDoc modeIter = modes.iterator();
226             while (modeIter.hasNext()) {
227                 String JavaDoc mode = (String JavaDoc) modeIter.next();
228                 if (mode.equals(fMode)) {
229                     String JavaDoc category = ext.getCategory();
230                     // NOTE: category can be null
231
if (categories!= null && !categories.contains(category)) {
232                         categories.add(category);
233                     }
234                     populateMenuItem(mode, ext, menu, accelerator++);
235                 }
236             }
237         }
238         
239     // add in the open ... dialog shortcut(s)
240
if (categories.isEmpty()) {
241             if (accelerator > 1) {
242                 new MenuItem(menu, SWT.SEPARATOR);
243             }
244             IAction action = new OpenLaunchDialogAction(fGroup.getIdentifier());
245             ActionContributionItem item = new ActionContributionItem(action);
246             item.fill(menu, -1);
247         } else {
248             boolean addedSep = false;
249             iter = categories.iterator();
250             while (iter.hasNext()) {
251                 // NOTE: category can be null
252
String JavaDoc category = (String JavaDoc) iter.next();
253                 ILaunchGroup group = fGroup;
254                 if (category != null) {
255                     group = (ILaunchGroup) fGroupsByCategory.get(category);
256                 }
257                 if (group != null) {
258                     if (accelerator > 1 && !addedSep) {
259                         new MenuItem(menu, SWT.SEPARATOR);
260                         addedSep = true;
261                     }
262                     IAction action = new OpenLaunchDialogAction(group.getIdentifier());
263                     ActionContributionItem item= new ActionContributionItem(action);
264                     item.fill(menu, -1);
265                 }
266             }
267         }
268
269     }
270
271     /**
272      * Evaluate the enablement logic in the contextualLaunch
273      * element description. A true result means that we should
274      * include this shortcut in the context menu.
275      * @return true iff shortcut should appear in context menu
276      */

277     private boolean isApplicable(LaunchShortcutExtension ext, IEvaluationContext context) throws CoreException {
278         Expression expr = ext.getContextualLaunchEnablementExpression();
279         return ext.evalEnablementExpression(context, expr);
280     }
281
282     /**
283      * Add the shortcut to the context menu's launch sub-menu.
284      */

285     private void populateMenuItem(String JavaDoc mode, LaunchShortcutExtension ext, Menu menu, int accelerator) {
286         LaunchShortcutAction action = new LaunchShortcutAction(mode, ext);
287         action.setActionDefinitionId(ext.getId() + "." + mode); //$NON-NLS-1$
288
String JavaDoc helpContextId = ext.getHelpContextId();
289         if (helpContextId != null) {
290             PlatformUI.getWorkbench().getHelpSystem().setHelp(action, helpContextId);
291         }
292         StringBuffer JavaDoc label= new StringBuffer JavaDoc();
293         if (accelerator >= 0 && accelerator < 10) {
294             //add the numerical accelerator
295
label.append('&');
296             label.append(accelerator);
297             label.append(' ');
298         }
299         String JavaDoc contextLabel= ext.getContextLabel(mode);
300         // replace default action label with context label if specified.
301
label.append((contextLabel != null) ? contextLabel : action.getText());
302         action.setText(label.toString());
303         ActionContributionItem item= new ActionContributionItem(action);
304         item.fill(menu, -1);
305     }
306
307     /**
308      * Returns the launch configuration manager.
309     *
310     * @return launch configuration manager
311     */

312     private LaunchConfigurationManager getLaunchConfigurationManager() {
313         return DebugUIPlugin.getDefault().getLaunchConfigurationManager();
314     }
315
316 }
317
Popular Tags