|
22 | 22 | import java.util.Map; |
23 | 23 | import java.util.Map.Entry; |
24 | 24 | import java.util.Set; |
| 25 | +import java.util.concurrent.CompletableFuture; |
25 | 26 |
|
26 | 27 | import org.eclipse.core.expressions.Expression; |
27 | 28 | import org.eclipse.core.expressions.IEvaluationContext; |
|
50 | 51 | import org.eclipse.swt.events.MenuAdapter; |
51 | 52 | import org.eclipse.swt.events.MenuEvent; |
52 | 53 | import org.eclipse.swt.widgets.Control; |
| 54 | +import org.eclipse.swt.widgets.Display; |
| 55 | +import org.eclipse.swt.widgets.Event; |
53 | 56 | import org.eclipse.swt.widgets.Menu; |
54 | 57 | import org.eclipse.swt.widgets.MenuItem; |
55 | 58 | import org.eclipse.ui.IEditorPart; |
@@ -205,92 +208,126 @@ protected void fillMenu(Menu menu) { |
205 | 208 | } |
206 | 209 | List<Object> selection = ss.toList(); |
207 | 210 | Object o = ss.getFirstElement(); |
208 | | - IEditorPart editor = null; |
| 211 | + final IEditorPart editor; |
209 | 212 | if(o instanceof IEditorPart editorPart) { |
210 | 213 | editor = editorPart; |
211 | 214 | selection.set(0, editorPart.getEditorInput()); |
| 215 | + } else { |
| 216 | + editor = null; |
212 | 217 | } |
| 218 | + |
213 | 219 | IEvaluationContext context = DebugUIPlugin.createEvaluationContext(selection); |
214 | 220 | context.setAllowPluginActivation(true); |
215 | 221 | context.addVariable("selection", selection); //$NON-NLS-1$ |
| 222 | + |
| 223 | + MenuItem loadingItem = new MenuItem(menu, SWT.NONE); |
| 224 | + loadingItem.setText(DebugUIMessages.ContextualLaunchAction_0); |
| 225 | + loadingItem.setEnabled(false); |
| 226 | + |
| 227 | + final int finalAcc = accelerator; |
| 228 | + CompletableFuture.supplyAsync(() -> filterShortcuts(context))// filtering can be a long-running operation |
| 229 | + .thenAccept(filteredShortcuts -> { |
| 230 | + |
| 231 | + // Run this in the UI thread so the menu can be populated |
| 232 | + Display.getDefault().syncExec(() -> { |
| 233 | + |
| 234 | + int internalAccelerator = finalAcc; |
| 235 | + // replace "Loading..." with actual stuff |
| 236 | + loadingItem.dispose(); |
| 237 | + |
| 238 | + // we need a separator iff the shared config entry has been added and there are |
| 239 | + // following shortcuts |
| 240 | + if (menu.getItemCount() > 0 && filteredShortcuts.size() > 0) { |
| 241 | + new MenuItem(menu, SWT.SEPARATOR); |
| 242 | + } |
| 243 | + |
| 244 | + List<String> categories = new ArrayList<>(); |
| 245 | + Map<LaunchShortcutExtension, ILaunchConfiguration[]> launchConfigurations = new LinkedHashMap<>(); |
| 246 | + for (LaunchShortcutExtension ext : filteredShortcuts) { |
| 247 | + for (String mode : ext.getModes()) { |
| 248 | + if (mode.equals(fMode)) { |
| 249 | + String category = ext.getCategory(); |
| 250 | + // NOTE: category can be null |
| 251 | + if (category != null && !categories.contains(category)) { |
| 252 | + categories.add(category); |
| 253 | + } |
| 254 | + populateMenuItem(mode, ext, menu, null, internalAccelerator++, null); |
| 255 | + ILaunchConfiguration[] configurations = editor != null |
| 256 | + ? ext.getLaunchConfigurations(editor) |
| 257 | + : ext.getLaunchConfigurations(ss); |
| 258 | + if (configurations != null) { |
| 259 | + launchConfigurations.put(ext, configurations); |
| 260 | + } |
| 261 | + } |
| 262 | + } |
| 263 | + } |
| 264 | + |
| 265 | + // add in the open ... dialog shortcut(s) |
| 266 | + if (categories.isEmpty()) { |
| 267 | + if (internalAccelerator > 1) { |
| 268 | + new MenuItem(menu, SWT.SEPARATOR); |
| 269 | + } |
| 270 | + IAction action = new OpenLaunchDialogAction(fGroup.getIdentifier()); |
| 271 | + ActionContributionItem item = new ActionContributionItem(action); |
| 272 | + item.fill(menu, -1); |
| 273 | + } else { |
| 274 | + boolean addedSep = false; |
| 275 | + for (String category : categories) { |
| 276 | + ILaunchGroup group = fGroup; |
| 277 | + if (category != null) { |
| 278 | + group = fGroupsByCategory.get(category); |
| 279 | + } |
| 280 | + if (group != null) { |
| 281 | + if (internalAccelerator > 1 && !addedSep) { |
| 282 | + new MenuItem(menu, SWT.SEPARATOR); |
| 283 | + addedSep = true; |
| 284 | + } |
| 285 | + IAction action = new OpenLaunchDialogAction(group.getIdentifier()); |
| 286 | + ActionContributionItem item= new ActionContributionItem(action); |
| 287 | + item.fill(menu, -1); |
| 288 | + } |
| 289 | + } |
| 290 | + } |
| 291 | + |
| 292 | + // now add collected launches |
| 293 | + Set<ILaunchConfiguration> added = new HashSet<>(); |
| 294 | + for (Entry<LaunchShortcutExtension, ILaunchConfiguration[]> entry : launchConfigurations.entrySet()) { |
| 295 | + for (ILaunchConfiguration configuration : entry.getValue()) { |
| 296 | + if (added.add(configuration)) { |
| 297 | + populateMenuItem(fMode, entry.getKey(), menu, configuration, internalAccelerator++, |
| 298 | + null); |
| 299 | + } |
| 300 | + } |
| 301 | + } |
| 302 | + |
| 303 | + // update UI |
| 304 | + Event event = new Event(); |
| 305 | + event.data = menu; |
| 306 | + menu.notifyListeners(SWT.Show, event); |
| 307 | + |
| 308 | + fFillMenu = false; |
| 309 | + }); |
| 310 | + }); |
| 311 | + } |
| 312 | + |
| 313 | + private List<LaunchShortcutExtension> filterShortcuts(IEvaluationContext context) { |
216 | 314 | List<LaunchShortcutExtension> allShortCuts = getLaunchConfigurationManager().getLaunchShortcuts(); |
217 | 315 | List<LaunchShortcutExtension> filteredShortCuts = new ArrayList<>(); |
218 | | - Iterator<LaunchShortcutExtension> iter = allShortCuts.iterator(); |
219 | | - while (iter.hasNext()) { |
220 | | - LaunchShortcutExtension ext = iter.next(); |
| 316 | + Iterator<LaunchShortcutExtension> allShortcutsIter = allShortCuts.iterator(); |
| 317 | + while (allShortcutsIter.hasNext()) { |
| 318 | + LaunchShortcutExtension shortcut = allShortcutsIter.next(); |
221 | 319 | try { |
222 | | - if (!WorkbenchActivityHelper.filterItem(ext) && isApplicable(ext, context)) { |
223 | | - filteredShortCuts.add(ext); |
| 320 | + if (!WorkbenchActivityHelper.filterItem(shortcut) && isApplicable(shortcut, context)) { |
| 321 | + filteredShortCuts.add(shortcut); |
224 | 322 | } |
225 | | - } |
226 | | - catch (CoreException e) { |
227 | | - IStatus status = new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Launch shortcut '" + ext.getId() + "' enablement expression caused exception. Shortcut was removed.", e); //$NON-NLS-1$ //$NON-NLS-2$ |
| 323 | + } catch (CoreException e) { |
| 324 | + IStatus status = new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Launch shortcut '" //$NON-NLS-1$ |
| 325 | + + shortcut.getId() + "' enablement expression caused exception. Shortcut was removed.", e); //$NON-NLS-1$ |
228 | 326 | DebugUIPlugin.log(status); |
229 | | - iter.remove(); |
230 | | - } |
231 | | - } |
232 | | - |
233 | | - //we need a separator iff the shared config entry has been added and there are following shortcuts |
234 | | - if(menu.getItemCount() > 0 && filteredShortCuts.size() > 0) { |
235 | | - new MenuItem(menu, SWT.SEPARATOR); |
236 | | - } |
237 | | - List<String> categories = new ArrayList<>(); |
238 | | - Map<LaunchShortcutExtension, ILaunchConfiguration[]> launchConfigurations = new LinkedHashMap<>(); |
239 | | - for(LaunchShortcutExtension ext : filteredShortCuts) { |
240 | | - for(String mode : ext.getModes()) { |
241 | | - if (mode.equals(fMode)) { |
242 | | - String category = ext.getCategory(); |
243 | | - // NOTE: category can be null |
244 | | - if (category != null && !categories.contains(category)) { |
245 | | - categories.add(category); |
246 | | - } |
247 | | - populateMenuItem(mode, ext, menu, null, accelerator++, null); |
248 | | - ILaunchConfiguration[] configurations = editor != null ? |
249 | | - ext.getLaunchConfigurations(editor) : |
250 | | - ext.getLaunchConfigurations(ss); |
251 | | - if (configurations != null) { |
252 | | - launchConfigurations.put(ext, configurations); |
253 | | - } |
254 | | - } |
255 | | - } |
256 | | - } |
257 | | - |
258 | | - // add in the open ... dialog shortcut(s) |
259 | | - if (categories.isEmpty()) { |
260 | | - if (accelerator > 1) { |
261 | | - new MenuItem(menu, SWT.SEPARATOR); |
262 | | - } |
263 | | - IAction action = new OpenLaunchDialogAction(fGroup.getIdentifier()); |
264 | | - ActionContributionItem item = new ActionContributionItem(action); |
265 | | - item.fill(menu, -1); |
266 | | - } else { |
267 | | - boolean addedSep = false; |
268 | | - for (String category : categories) { |
269 | | - ILaunchGroup group = fGroup; |
270 | | - if (category != null) { |
271 | | - group = fGroupsByCategory.get(category); |
272 | | - } |
273 | | - if (group != null) { |
274 | | - if (accelerator > 1 && !addedSep) { |
275 | | - new MenuItem(menu, SWT.SEPARATOR); |
276 | | - addedSep = true; |
277 | | - } |
278 | | - IAction action = new OpenLaunchDialogAction(group.getIdentifier()); |
279 | | - ActionContributionItem item= new ActionContributionItem(action); |
280 | | - item.fill(menu, -1); |
281 | | - } |
| 327 | + allShortcutsIter.remove(); |
282 | 328 | } |
283 | 329 | } |
284 | | - // now add collected launches |
285 | | - Set<ILaunchConfiguration> added = new HashSet<>(); |
286 | | - for (Entry<LaunchShortcutExtension, ILaunchConfiguration[]> entry : launchConfigurations.entrySet()) { |
287 | | - for (ILaunchConfiguration configuration : entry.getValue()) { |
288 | | - if (added.add(configuration)) { |
289 | | - populateMenuItem(fMode, entry.getKey(), menu, configuration, accelerator++, null); |
290 | | - } |
291 | | - } |
292 | | - } |
293 | | - |
| 330 | + return filteredShortCuts; |
294 | 331 | } |
295 | 332 |
|
296 | 333 | /** |
|
0 commit comments