Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 18338 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.properties (+4 lines)
Lines 188-193 Link Here
188
188
189
SourceContainerPresentationsName = Source Container Presentations
189
SourceContainerPresentationsName = Source Container Presentations
190
190
191
#---Chris' work in progress
192
LaunchMenu.label=&Run
193
LaunchMenuNoneApplicable.label=(None Applicable)
194
191
containerName.workingSet = Working set
195
containerName.workingSet = Working set
192
sourceNotFoundEditorName=Source Not Found Editor
196
sourceNotFoundEditorName=Source Not Found Editor
193
197
(-)plugin.xml (-1 / +20 lines)
Lines 1507-1511 Link Here
1507
            id="org.eclipse.debug.ui.containerPresentation.default">
1507
            id="org.eclipse.debug.ui.containerPresentation.default">
1508
      </sourceContainerPresentation>
1508
      </sourceContainerPresentation>
1509
   </extension>
1509
   </extension>
1510
    
1510
<!-- ========================================= -->
1511
<!-- Contextual Launch Menu (Work in Progress) -->
1512
<!-- ========================================= -->
1513
   <extension
1514
         point="org.eclipse.ui.popupMenus">
1515
      <objectContribution
1516
            objectClass="org.eclipse.core.resources.IResource"
1517
            adaptable="true"
1518
            id="org.eclipse.debug.ui.contextualLaunch">
1519
        <action
1520
               label="%LaunchMenu.label"
1521
               style="pulldown"
1522
               class="org.eclipse.debug.internal.ui.actions.ContextualLaunchObjectActionDelegate"
1523
               menubarPath="additions"
1524
               enablesFor="1"
1525
               id="org.eclipse.debug.ui.contextualLaunch.submenu">
1526
         </action>
1527
      </objectContribution>
1528
	</extension>
1529
<!-- End Contextual Run Menu (Work in Progress) -->
1511
</plugin>
1530
</plugin>
(-)schema/launchShortcuts.exsd (-4 / +78 lines)
Lines 3-9 Link Here
3
<schema targetNamespace="org.eclipse.debug.ui">
3
<schema targetNamespace="org.eclipse.debug.ui">
4
<annotation>
4
<annotation>
5
      <appInfo>
5
      <appInfo>
6
         <meta.schema plugin="org.eclipse.debug.ui" id="launchShortcuts" name="Launch Shortcuts"/>
6
         <meta.schema plugin="org.eclipse.debug.ui" id="filaunchShortcuts" name="Launch Shortcuts"/>
7
      </appInfo>
7
      </appInfo>
8
      <documentation>
8
      <documentation>
9
         This extension point provides support for selection sensitive launching.  Extensions register a shortcut which
9
         This extension point provides support for selection sensitive launching.  Extensions register a shortcut which
Lines 49-54 Link Here
49
      <complexType>
49
      <complexType>
50
         <sequence>
50
         <sequence>
51
            <element ref="perspective" minOccurs="0" maxOccurs="unbounded"/>
51
            <element ref="perspective" minOccurs="0" maxOccurs="unbounded"/>
52
            <element ref="filter" minOccurs="0" maxOccurs="unbounded"/>
53
            <element ref="contextLabel" minOccurs="0" maxOccurs="unbounded"/>
52
         </sequence>
54
         </sequence>
53
         <attribute name="id" type="string" use="required">
55
         <attribute name="id" type="string" use="required">
54
            <annotation>
56
            <annotation>
Lines 106-111 Link Here
106
               </documentation>
108
               </documentation>
107
            </annotation>
109
            </annotation>
108
         </attribute>
110
         </attribute>
111
         <attribute name="contextLabel" type="string">
112
            <annotation>
113
               <documentation>
114
                  an optional attribute that specifies the label to appear in the contextual launch menu (if this shortcut is not filtered according to the rules described in the filterClass attribute). If unspecified, the &lt;samp&gt;label&lt;/samp&gt; attribute will be used instead.
115
               </documentation>
116
            </annotation>
117
         </attribute>
118
         <attribute name="filterClass" type="string">
119
            <annotation>
120
               <documentation>
121
                  an optional attribute that specifies the fully qualified path of a Java class that implements the &lt;samp&gt;org.eclipse.ui.IActionFilter&lt;/samp&gt; interface. The testAttribute() method is called with the selected resource and the name/value pair specified by subsequent filter elements. If all return values of all filter elements are true, the shortcut will appear in the contextual launch menu of the selected resource. If the filterClass attribute is not specifies, the shortcut will not appear in the contextual launch menu. If the filterClass is specified, but no filter elements are found, the shortcut will appear in the menu.
122
               </documentation>
123
            </annotation>
124
         </attribute>
109
      </complexType>
125
      </complexType>
110
   </element>
126
   </element>
111
127
Lines 121-126 Link Here
121
      </complexType>
137
      </complexType>
122
   </element>
138
   </element>
123
139
140
   <element name="filter">
141
      <annotation>
142
         <documentation>
143
            specifies the name/value pair that will be tested for boolean true/false by calling the &lt;samp&gt;org.eclipse.ui.IActionFilter:testAttribute()&lt;/samp&gt; method of the class specified by the &lt;samp&gt;filterClass&lt;/samp&gt; attribute of the parent &lt;samp&gt;shortcut&lt;/samp&gt; element. If all filters return a true value, the shortcut will be visible in the contextual launch menu.
144
         </documentation>
145
      </annotation>
146
      <complexType>
147
         <attribute name="name" type="string" use="required">
148
            <annotation>
149
               <documentation>
150
                  specifies the name of the filter property.
151
               </documentation>
152
            </annotation>
153
         </attribute>
154
         <attribute name="value" type="string" use="required">
155
            <annotation>
156
               <documentation>
157
                  specifies the expected value of the filter property.
158
               </documentation>
159
            </annotation>
160
         </attribute>
161
      </complexType>
162
   </element>
163
164
   <element name="contextLabel">
165
      <annotation>
166
         <documentation>
167
            Specify the label for a contextual launch mode.
168
         </documentation>
169
      </annotation>
170
      <complexType>
171
         <attribute name="mode" use="required">
172
            <annotation>
173
               <documentation>
174
                  specifies a mode from the set {&quot;run&quot;,&quot;debug&quot;,&quot;profile&quot;}
175
               </documentation>
176
            </annotation>
177
            <simpleType>
178
               <restriction base="string">
179
                  <enumeration value="run">
180
                  </enumeration>
181
                  <enumeration value="debug">
182
                  </enumeration>
183
                  <enumeration value="profile">
184
                  </enumeration>
185
               </restriction>
186
            </simpleType>
187
         </attribute>
188
         <attribute name="label" type="string" use="required">
189
            <annotation>
190
               <documentation>
191
                  specifies the label to appear in the contextual launch menu.
192
               </documentation>
193
            </annotation>
194
         </attribute>
195
      </complexType>
196
   </element>
197
124
   <annotation>
198
   <annotation>
125
      <appInfo>
199
      <appInfo>
126
         <meta.section type="examples"/>
200
         <meta.section type="examples"/>
Lines 165-173 Link Here
165
      </appInfo>
239
      </appInfo>
166
      <documentation>
240
      <documentation>
167
         &lt;p&gt;
241
         &lt;p&gt;
168
&lt;a href="hglegal.htm"&gt;
242
&lt;a href=&quot;hglegal.htm&quot;&gt;
169
 &lt;img SRC="ngibmcpy.gif"
243
 &lt;img SRC=&quot;ngibmcpy.gif&quot;
170
   ALT="Copyright (c) 2000, 2003 IBM Corporation and others. All Rights Reserved."
244
   ALT=&quot;Copyright (c) 2000, 2003 IBM Corporation and others. All Rights Reserved.&quot;
171
   BORDER=0 height=14 width=324&gt;&lt;/a&gt;
245
   BORDER=0 height=14 width=324&gt;&lt;/a&gt;
172
&lt;/p&gt;
246
&lt;/p&gt;
173
      </documentation>
247
      </documentation>
(-)ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationManager.java (-3 / +3 lines)
Lines 512-522 Link Here
512
	
512
	
513
	/**
513
	/**
514
	 * Returns all launch shortcuts defined for the given perspective,
514
	 * Returns all launch shortcuts defined for the given perspective,
515
	 * or <code>null</code> if none
515
	 * empty list if none.
516
	 * 
516
	 * 
517
	 * @param perpsective perspective identifier
517
	 * @param perpsective perspective identifier
518
	 * @return all launch shortcuts defined for the given perspective,
518
	 * @return all launch shortcuts defined for the given perspective,
519
	 * or <code>null</code> if none
519
	 * empty list if none.
520
	 */
520
	 */
521
	public List getLaunchShortcuts(String perpsective, String category) {
521
	public List getLaunchShortcuts(String perpsective, String category) {
522
		if (fLaunchShortcutsByPerspective == null) {
522
		if (fLaunchShortcutsByPerspective == null) {
Lines 538-544 Link Here
538
		}
538
		}
539
		List list = (List)fLaunchShortcutsByPerspective.get(perpsective); 
539
		List list = (List)fLaunchShortcutsByPerspective.get(perpsective); 
540
		if (list == null) {
540
		if (list == null) {
541
			return null;
541
			return new ArrayList();
542
		} else {
542
		} else {
543
			return filterShortcuts(list, category);
543
			return filterShortcuts(list, category);
544
		}
544
		}
(-)ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchShortcutExtension.java (-1 / +68 lines)
Lines 15-20 Link Here
15
import java.net.URL;
15
import java.net.URL;
16
import java.util.ArrayList;
16
import java.util.ArrayList;
17
import java.util.HashSet;
17
import java.util.HashSet;
18
import java.util.Iterator;
18
import java.util.List;
19
import java.util.List;
19
import java.util.Set;
20
import java.util.Set;
20
import java.util.StringTokenizer;
21
import java.util.StringTokenizer;
Lines 22-30 Link Here
22
import org.eclipse.core.runtime.CoreException;
23
import org.eclipse.core.runtime.CoreException;
23
import org.eclipse.core.runtime.IConfigurationElement;
24
import org.eclipse.core.runtime.IConfigurationElement;
24
import org.eclipse.debug.internal.ui.DebugUIPlugin;
25
import org.eclipse.debug.internal.ui.DebugUIPlugin;
26
import org.eclipse.debug.internal.ui.Pair;
25
import org.eclipse.debug.ui.ILaunchShortcut;
27
import org.eclipse.debug.ui.ILaunchShortcut;
26
import org.eclipse.jface.resource.ImageDescriptor;
28
import org.eclipse.jface.resource.ImageDescriptor;
27
import org.eclipse.jface.viewers.ISelection;
29
import org.eclipse.jface.viewers.ISelection;
30
import org.eclipse.ui.IActionFilter;
28
import org.eclipse.ui.IEditorPart;
31
import org.eclipse.ui.IEditorPart;
29
32
30
33
Lines 37-47 Link Here
37
	private List fPerspectives = null;
40
	private List fPerspectives = null;
38
	private ILaunchShortcut fDelegate = null;
41
	private ILaunchShortcut fDelegate = null;
39
	private Set fModes = null;
42
	private Set fModes = null;
43
	private IActionFilter fActionFilter = null;
44
	private /* <Pair> */ List fFilters = null;
40
	
45
	
41
	/**
46
	/**
42
	 * The configuration element defining this tab.
47
	 * The configuration element defining this tab.
43
	 */
48
	 */
44
	private IConfigurationElement fConfig;
49
	private IConfigurationElement fConfig;
50
	private /* <Pair> */ List fContextLabels;
45
	
51
	
46
	/**
52
	/**
47
	 * Constructs a launch configuration tab extension based
53
	 * Constructs a launch configuration tab extension based
Lines 72-78 Link Here
72
	 * @param configuration element that defines the attributes
78
	 * @param configuration element that defines the attributes
73
	 *  for this launch configuration tab extension
79
	 *  for this launch configuration tab extension
74
	 */
80
	 */
75
	protected IConfigurationElement getConfigurationElement() {
81
	public IConfigurationElement getConfigurationElement() {
76
		return fConfig;
82
		return fConfig;
77
	}
83
	}
78
	
84
	
Lines 86-91 Link Here
86
		return getConfigurationElement().getAttribute("label"); //$NON-NLS-1$
92
		return getConfigurationElement().getAttribute("label"); //$NON-NLS-1$
87
	}
93
	}
88
	
94
	
95
	/**
96
	 * Returns the contextual launch label of this shortcut
97
	 * 
98
	 * @return the contextual label of this shortcut, or <code>null</code> if not
99
	 *  specified
100
	 */
101
	public String getContextLabel(String mode) {
102
		// remember the list of context labels for this shortcut
103
		if (fContextLabels == null) {
104
			IConfigurationElement[] labels = getConfigurationElement().getChildren("contextLabel"); //$NON-NLS-1$
105
			fContextLabels = new ArrayList(labels.length);
106
			for (int i = 0; i < labels.length; i++) {
107
				fContextLabels.add(new Pair(labels[i].getAttribute("mode"),
108
						labels[i].getAttribute("label"))); //$NON-NLS-1$
109
			}
110
		}
111
		// pick out the first occurance of the "name" bound to "mode"
112
		Iterator iter = fContextLabels.iterator();
113
		while (iter.hasNext()) {
114
			Pair p = (Pair) iter.next();
115
			if (p.firstAsString().equals(mode)) {
116
				return p.secondAsString();
117
			}
118
		}
119
		return "no label";
120
	}
121
	
122
	/**
123
	 * Returns the filter class of this shortcut.
124
	 * 
125
	 * @return the filter class of this shortcut., or <code>null</code> if not
126
	 *  specified
127
	 */
128
	public IActionFilter getFilterClass() {
129
		if (fActionFilter == null) {
130
			try {
131
				fActionFilter = (IActionFilter)fConfig.createExecutableExtension("filterClass"); //$NON-NLS-1$
132
			} catch (CoreException e) {
133
				// silently ignore because filterClass is optional
134
				// DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), LaunchConfigurationsMessages.getString("LaunchShortcutExtension.Error_4"), LaunchConfigurationsMessages.getString("LaunchShortcutExtension.Unable_to_use_launch_shortcut_5"), e.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$
135
			}
136
		}
137
		return fActionFilter;
138
	}
139
	/**
140
	 * Returns all of the filter elements of this shortcut as a List of String Pairs.
141
	 * 
142
	 * @return all of the filter elements of this shortcut., or <code>null</code> if not
143
	 *  specified
144
	 */
145
	public /* <Pair> */ List getFilters() {
146
		if (fFilters == null) {
147
			IConfigurationElement[] filters = getConfigurationElement().getChildren("filter"); //$NON-NLS-1$
148
			fFilters = new ArrayList(filters.length);
149
			for (int i = 0; i < filters.length; i++) {
150
				fFilters.add(new Pair(filters[i].getAttribute("name"),
151
						filters[i].getAttribute("value"))); //$NON-NLS-1$
152
			}
153
		}
154
		return fFilters;
155
	}
89
	/**
156
	/**
90
	 * Returns the id of this shortcut
157
	 * Returns the id of this shortcut
91
	 * 
158
	 * 
(-)ui/org/eclipse/debug/internal/ui/Pair.java (+45 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2003, 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.debug.internal.ui;
12
13
/**
14
 * @author chris@tilts.net
15
 *
16
 * Pair is a basic tuple of two with classic first and second members.
17
 * Since Java is non-polymorphic, we use Object(s) for the pair elements
18
 * and cast our brains out.
19
 */
20
public class Pair {
21
	public Object fFirst = null;
22
	public Object fSecond = null;
23
	public Pair(Object first, Object second) {
24
		fFirst = first;
25
		fSecond = second;
26
	}
27
	/*
28
	 * String accessors
29
	 */
30
	public String firstAsString() {
31
		return (String) fFirst;
32
	}
33
	public String secondAsString() {
34
		return (String) fSecond;
35
	}
36
	/*
37
	 * Integer accessors
38
	 */
39
	public Integer firstAsInteger() {
40
		return (Integer) fFirst;
41
	}
42
	public Integer secondAsInteger() {
43
		return (Integer) fSecond;
44
	}
45
}
(-)ui/org/eclipse/debug/internal/ui/actions/ContextualLaunchObjectActionDelegate.java (+327 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2003, 2004 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.debug.internal.ui.actions;
12
13
import java.util.ArrayList;
14
import java.util.Iterator;
15
import java.util.List;
16
import java.util.Set;
17
18
import org.eclipse.core.runtime.IExtension;
19
import org.eclipse.core.runtime.IPluginDescriptor;
20
import org.eclipse.debug.internal.ui.DebugUIPlugin;
21
import org.eclipse.debug.internal.ui.Pair;
22
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
23
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchGroupExtension;
24
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
25
import org.eclipse.jface.action.Action;
26
import org.eclipse.jface.action.ActionContributionItem;
27
import org.eclipse.jface.action.IAction;
28
import org.eclipse.jface.action.IMenuCreator;
29
import org.eclipse.jface.viewers.ISelection;
30
import org.eclipse.jface.viewers.IStructuredSelection;
31
import org.eclipse.swt.events.MenuAdapter;
32
import org.eclipse.swt.events.MenuEvent;
33
import org.eclipse.swt.widgets.Control;
34
import org.eclipse.swt.widgets.Menu;
35
import org.eclipse.swt.widgets.MenuItem;
36
import org.eclipse.ui.IActionFilter;
37
import org.eclipse.ui.IObjectActionDelegate;
38
import org.eclipse.ui.IPerspectiveDescriptor;
39
import org.eclipse.ui.IWorkbenchPage;
40
import org.eclipse.ui.IWorkbenchPart;
41
import org.eclipse.ui.IWorkbenchWindow;
42
import org.eclipse.ui.help.WorkbenchHelp;
43
44
/**
45
 * An action delegate that builds a context menu with applicable launch shortcuts.
46
 * <p>
47
 * This class can be contributed as pop-up menu extension action. When envolked,
48
 * it becomes a sub-menu that dynamically builds a list of applicable shortcuts
49
 * for the current selection (ISelection in the workspace). The LaunchShortCut
50
 * extension is consulted to obtain the list of registered short cuts. Each short
51
 * cut may have optional information to support a context menu action. The extra
52
 * information includes a "filterClass", a list of "contextLabel"s, and a list of
53
 * "filter" elements. ContextLabels allow custom labels to appear for any mode
54
 * (run, debug, profile, etc.) in the contextual launch sub-menu. The filterClass
55
 * is loaded and run over the list of "filter" elements to determine if the
56
 * shortcut extension item is appropriate for the selected resource.
57
 * <p>
58
 * An example is the JDT Java Applet extension, which is only applicable on files
59
 * of extension "*.java" and being a sub-class of type Applet. Note that it is up
60
 * to the filterClass to provide attributes and methods to implement the test. In
61
 * this example, we have extended the AppletShortcut to implement the IActionFilter
62
 * interface so that it can function as the filterClass, adding only a testAttribute()
63
 * method.
64
 * <p>
65
 * <pre>
66
 * &lt;shortcut
67
 *          label="%AppletShortcut.label"
68
 *           icon="icons/full/ctool16/java_applet.gif"
69
 *           helpContextId="org.eclipse.jdt.debug.ui.shortcut_java_applet"
70
 *           modes="run, debug"
71
 *           filterClass="org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletLaunchShortcut"
72
 *           class="org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletLaunchShortcut"
73
 *           id="org.eclipse.jdt.debug.ui.javaAppletShortcut"&gt;
74
 *        &lt;filter
75
 *           name="NameMatches"
76
 *           value="*.java"/&gt;
77
 *        &lt;filter
78
 *        	name="ContextualLaunchActionFilter"
79
 *        	value="supportsContextualLaunch"/&gt;
80
 *        &lt;contextLabel
81
 *        	mode="run"
82
 *        	label="%RunJavaApplet.label"/&gt;
83
 * 		 &lt;contextLabel
84
 * 		 	mode="debug"
85
 * 		 	label="%DebugJavaApplet.label"/&gt;
86
 * 		  ...
87
 *   &lt;shortcut&gt;
88
 * </pre>
89
 */
90
public class ContextualLaunchObjectActionDelegate
91
		implements
92
			IObjectActionDelegate,
93
			IMenuCreator {
94
95
	private ISelection fSelection;
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 repopulate the menu each time
124
		 * it is shown because MenuManager.update(boolean, boolean) 
125
		 * doesn't dispose pulldown ActionContribution items for each popup menu.
126
		 */
127
		menu.addMenuListener(new MenuAdapter() {
128
			public void menuShown(MenuEvent e) {
129
				Menu m = (Menu)e.widget;
130
				MenuItem[] items = m.getItems();
131
				for (int i=0; i < items.length; i++) {
132
					items[i].dispose();
133
				}
134
				fillMenu(m);
135
			}
136
		});
137
		return menu;
138
	}
139
140
	/*
141
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
142
	 */
143
	public void run(IAction action) {
144
		// Never called because we become a menu.
145
	}
146
	
147
	IAction delegateAction;
148
	/*
149
	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
150
	 */
151
	public void selectionChanged(IAction action, ISelection selection) {
152
		if (((IStructuredSelection) selection).size() != 1)
153
			action.setEnabled(false);	// Can only handle one resource at a time
154
		else {
155
			if (action instanceof Action) {
156
				if (delegateAction != action) {
157
					delegateAction = (Action) action;
158
					delegateAction.setMenuCreator(this);
159
				}
160
				action.setEnabled(true);
161
				fSelection = selection;
162
			} else {
163
				action.setEnabled(false);
164
			}
165
		}
166
	}
167
168
	private int fCount = 0;
169
	/**
170
	 * Fill pull down menu with the pages of the JTabbedPane
171
	 */
172
	protected void fillMenu(Menu menu) {
173
		// lookup appropriate launch config types and build launch actions for them.
174
		// Retrieve the current perspective and the registered shortcuts
175
		String activePerspID = getActivePerspectiveID();
176
		if (activePerspID == null || fSelection == null) {
177
			return;
178
		}
179
		// gather all shortcuts and run their filters so that we only run the
180
		// filters one time for each shortcut. Running filters can be expensive.
181
		// Also, only *LOADED* plugins get their filters run.
182
		List /* <LaunchShortcutExtension> */ allShortCuts = getLaunchConfigurationManager().getLaunchShortcuts();
183
		Iterator iter = allShortCuts.iterator();
184
		List filteredShortCuts = new ArrayList(10);
185
		while (iter.hasNext()) {
186
			LaunchShortcutExtension ext = (LaunchShortcutExtension) iter.next();
187
			if (isApplicable(ext)) {
188
				filteredShortCuts.add(ext);
189
			}
190
		}
191
		iter = filteredShortCuts.iterator();
192
		if (iter.hasNext()) {
193
			while (iter.hasNext()) {
194
				LaunchShortcutExtension ext = (LaunchShortcutExtension) iter.next();
195
				Set modes = ext.getModes(); // supported launch modes
196
				Iterator modeIter = modes.iterator();
197
				while (modeIter.hasNext()) {
198
					String mode = (String) modeIter.next();
199
					populateMenu(mode, ext, menu);
200
				}
201
			}
202
		} else {
203
			// put in a fake action to show there are none
204
//			IAction action = new FakeAction("{ }");
205
//			ActionContributionItem item= new ActionContributionItem(action);
206
//			item.fill(menu, -1);
207
		}
208
	}
209
	
210
	private IActionFilter getFilterClassIfLoaded(LaunchShortcutExtension ext) {
211
		IExtension extensionPoint = ext.getConfigurationElement().getDeclaringExtension();
212
		IPluginDescriptor pluginDescriptor = extensionPoint.getDeclaringPluginDescriptor();
213
		if (pluginDescriptor.isPluginActivated()) {
214
			IActionFilter filter = ext.getFilterClass();
215
			return filter;
216
		} else {
217
			return null;
218
		}
219
	}
220
	/* (non-javadoc)
221
	 * Apply contextFilters for this extension to decide visibility. 
222
	 *
223
 	 * @return true if this shortcut should appear in the contextual launch menu
224
	 */
225
	private boolean isApplicable(LaunchShortcutExtension ext) {
226
		// boolean hasMode = ext.getModes().contains(getMode(launchGroupIdentifier));
227
		// return false if there isn't a filter class or there are no filters specified by the shortcut
228
		// Only loaded plugins will be used, so the actionFilter is null if the filterClass is not loaded
229
		IActionFilter actionFilter = getFilterClassIfLoaded(ext);
230
		if (actionFilter == null) {
231
			return false;
232
		}
233
		List filters = ext.getFilters();
234
		if (filters.isEmpty()) {
235
			return false;
236
		}
237
		Iterator iter = filters.listIterator();
238
		while (iter.hasNext()) {
239
			Pair pair = (Pair) iter.next();
240
			String name = pair.firstAsString();
241
			String value= pair.secondAsString();
242
			Object target = (Object) fSelection;
243
			// any filter that returns false makes the shortcut non-visible
244
			if (!actionFilter.testAttribute(target,name,value)) {
245
				return false;
246
			}
247
		}
248
		return true;
249
	}
250
	/* Add the shortcut to the context menu's launch submenu.
251
	 * 
252
	 */
253
	private void populateMenu(String mode, LaunchShortcutExtension ext, Menu menu) {
254
		LaunchShortcutAction action = new LaunchShortcutAction(mode, ext);
255
		action.setActionDefinitionId(ext.getId());
256
		String helpContextId = ext.getHelpContextId();
257
		if (helpContextId != null) {
258
			WorkbenchHelp.setHelp(action, helpContextId);
259
		}
260
		// replace default action label with context label if specified.
261
		String label = ext.getContextLabel(mode);
262
		label = (label != null) ? label : action.getText();
263
		action.setText(label);
264
		ActionContributionItem item= new ActionContributionItem(action);
265
		item.fill(menu, -1);
266
	}
267
	
268
	private class FakeAction extends Action {
269
		public FakeAction(String name) {
270
			super(name);
271
		}
272
		public void run() {
273
		}
274
	}
275
/**
276
 * Return the ID of the currently active perspective.
277
 * 
278
 * @return the active perspective ID or <code>null</code> if there is none.
279
 */
280
private String getActivePerspectiveID() {
281
	IWorkbenchWindow window = DebugUIPlugin.getActiveWorkbenchWindow();
282
	if (window != null) {
283
		IWorkbenchPage page = window.getActivePage();
284
		if (page != null) {
285
			IPerspectiveDescriptor persp = page.getPerspective();
286
			if (persp != null) {
287
				return persp.getId();
288
			}
289
		}
290
	}
291
	return null;
292
}
293
/**
294
 * Returns the launch configuration manager.
295
*
296
* @return launch configuration manager
297
*/
298
private LaunchConfigurationManager getLaunchConfigurationManager() {
299
return DebugUIPlugin.getDefault().getLaunchConfigurationManager();
300
}
301
/**
302
 * Returns the launch group associatd with this action.
303
 * 
304
 * @return the launch group associatd with this action
305
 */
306
private LaunchGroupExtension getLaunchGroup(String fLaunchGroupIdentifier) {
307
	return getLaunchConfigurationManager().getLaunchGroup(fLaunchGroupIdentifier);
308
}
309
/**
310
 * Returns the mode of this action - run or debug 
311
 * 
312
 * @return the mode of this action - run or debug
313
 */
314
private String getMode(String fLaunchGroupIdentifier) {
315
	return getLaunchGroup(fLaunchGroupIdentifier).getMode();
316
}
317
318
/**
319
 * Returns the category of this action - possibly <code>null</code>
320
 *
321
 * @return the category of this action - possibly <code>null</code>
322
 */
323
private String getCategory(String fLaunchGroupIdentifier) {
324
	return getLaunchGroup(fLaunchGroupIdentifier).getCategory();
325
}
326
327
}

Return to bug 18338