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 325392 | Differences between
and this patch

Collapse All | Expand All

(-)model/UIElements.ecore (+5 lines)
Lines 310-315 Link Here
310
        <eStructuralFeatures xsi:type="ecore:EAttribute" name="contributionItem" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"
310
        <eStructuralFeatures xsi:type="ecore:EAttribute" name="contributionItem" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"
311
            transient="true"/>
311
            transient="true"/>
312
      </eClassifiers>
312
      </eClassifiers>
313
      <eClassifiers xsi:type="ecore:EClass" name="OpaqueMenuItem" eSuperTypes="#//ui/menu/MenuElement">
314
        <eStructuralFeatures xsi:type="ecore:EAttribute" name="opaqueItem" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"
315
            transient="true"/>
316
      </eClassifiers>
317
      <eClassifiers xsi:type="ecore:EClass" name="OpaqueMenu" eSuperTypes="#//ui/menu/Menu"/>
313
    </eSubpackages>
318
    </eSubpackages>
314
    <eSubpackages name="basic" nsURI="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic"
319
    <eSubpackages name="basic" nsURI="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic"
315
        nsPrefix="basic">
320
        nsPrefix="basic">
(-)UIAllTests.launch (-1 / +1 lines)
Lines 27-33 Link Here
27
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
27
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
28
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
28
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
29
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
29
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
30
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
30
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
31
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.e4.ui.tests.UIAllTests"/>
31
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.e4.ui.tests.UIAllTests"/>
32
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl}"/>
32
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl}"/>
33
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.e4.ui.tests"/>
33
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.e4.ui.tests"/>
(-)src/org/eclipse/e4/ui/tests/workbench/MMenuItemTest.java (-14 / +146 lines)
Lines 34-44 Link Here
34
import org.eclipse.e4.ui.model.application.ui.menu.MMenuItem;
34
import org.eclipse.e4.ui.model.application.ui.menu.MMenuItem;
35
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
35
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
36
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
36
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
37
import org.eclipse.e4.ui.workbench.renderers.swt.MenuRenderer;
37
import org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer;
38
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
38
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
39
import org.eclipse.jface.action.IContributionItem;
40
import org.eclipse.jface.action.MenuManager;
39
import org.eclipse.swt.SWT;
41
import org.eclipse.swt.SWT;
40
import org.eclipse.swt.widgets.Event;
42
import org.eclipse.swt.widgets.Event;
43
import org.eclipse.swt.widgets.Menu;
41
import org.eclipse.swt.widgets.MenuItem;
44
import org.eclipse.swt.widgets.MenuItem;
45
import org.eclipse.swt.widgets.Widget;
42
46
43
public class MMenuItemTest extends TestCase {
47
public class MMenuItemTest extends TestCase {
44
	protected IEclipseContext appContext;
48
	protected IEclipseContext appContext;
Lines 82-87 Link Here
82
		wb = new E4Workbench(window, appContext);
86
		wb = new E4Workbench(window, appContext);
83
		wb.createAndRunUI(window);
87
		wb.createAndRunUI(window);
84
88
89
		((MenuManager) ((Widget) menu.getWidget()).getData()).updateAll(true);
90
85
		Object widget = menuItem.getWidget();
91
		Object widget = menuItem.getWidget();
86
		assertNotNull(widget);
92
		assertNotNull(widget);
87
		assertTrue(widget instanceof MenuItem);
93
		assertTrue(widget instanceof MenuItem);
Lines 157-162 Link Here
157
		wb = new E4Workbench(window, appContext);
163
		wb = new E4Workbench(window, appContext);
158
		wb.createAndRunUI(window);
164
		wb.createAndRunUI(window);
159
165
166
		((MenuManager) ((Widget) menu.getWidget()).getData()).updateAll(true);
167
160
		Object widget1 = menuItem1.getWidget();
168
		Object widget1 = menuItem1.getWidget();
161
		assertNotNull(widget1);
169
		assertNotNull(widget1);
162
		assertTrue(widget1 instanceof MenuItem);
170
		assertTrue(widget1 instanceof MenuItem);
Lines 212-217 Link Here
212
		wb = new E4Workbench(window, appContext);
220
		wb = new E4Workbench(window, appContext);
213
		wb.createAndRunUI(window);
221
		wb.createAndRunUI(window);
214
222
223
		((MenuManager) ((Widget) menu.getWidget()).getData()).updateAll(true);
224
215
		Object widget1 = menuItem.getWidget();
225
		Object widget1 = menuItem.getWidget();
216
		assertNotNull(widget1);
226
		assertNotNull(widget1);
217
		assertTrue(widget1 instanceof MenuItem);
227
		assertTrue(widget1 instanceof MenuItem);
Lines 228-234 Link Here
228
		MCommand command = CommandsFactoryImpl.eINSTANCE.createCommand();
238
		MCommand command = CommandsFactoryImpl.eINSTANCE.createCommand();
229
239
230
		command.setElementId("commandId");
240
		command.setElementId("commandId");
231
		command.setCommandName("CommandForTest");
232
241
233
		menuItem.setCommand(command);
242
		menuItem.setCommand(command);
234
		menuItem.setType(ItemType.CHECK);
243
		menuItem.setType(ItemType.CHECK);
Lines 240-252 Link Here
240
		MApplication application = ApplicationFactoryImpl.eINSTANCE
249
		MApplication application = ApplicationFactoryImpl.eINSTANCE
241
				.createApplication();
250
				.createApplication();
242
		application.getChildren().add(window);
251
		application.getChildren().add(window);
243
		application.getCommands().add(command);
244
		application.setContext(appContext);
252
		application.setContext(appContext);
245
		appContext.set(MApplication.class.getName(), application);
253
		appContext.set(MApplication.class.getName(), application);
246
254
247
		wb = new E4Workbench(window, appContext);
255
		wb = new E4Workbench(window, appContext);
248
		wb.createAndRunUI(window);
256
		wb.createAndRunUI(window);
249
257
258
		MenuManager barManager = (MenuManager) ((Menu) menu.getWidget())
259
				.getData();
260
		barManager.updateAll(true);
261
250
		Object widget1 = menuItem.getWidget();
262
		Object widget1 = menuItem.getWidget();
251
		assertNotNull(widget1);
263
		assertNotNull(widget1);
252
		assertTrue(widget1 instanceof MenuItem);
264
		assertTrue(widget1 instanceof MenuItem);
Lines 255-261 Link Here
255
		assertTrue(menuItemWidget.getSelection());
267
		assertTrue(menuItemWidget.getSelection());
256
	}
268
	}
257
269
258
	public void XXXtestSubMenuCreation() throws Exception {
270
	public void testSubMenuCreation() throws Exception {
259
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
271
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
260
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
272
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
261
		menuBar.setElementId("org.eclipse.ui.main.menu");
273
		menuBar.setElementId("org.eclipse.ui.main.menu");
Lines 289-297 Link Here
289
		wb = new E4Workbench(window, appContext);
301
		wb = new E4Workbench(window, appContext);
290
		wb.createAndRunUI(window);
302
		wb.createAndRunUI(window);
291
303
304
		MenuManagerRenderer renderer = getRenderer(appContext, menuBar);
305
		MenuManager manager = renderer.getManager(menuBar);
306
		assertNotNull("failed to create menu bar manager", manager);
307
308
		assertEquals(1, manager.getSize());
309
310
		MenuManager fileManager = (MenuManager) manager.getItems()[0];
311
		MenuManager fileR = renderer.getManager(fileMenu);
312
		assertEquals(fileManager, fileR);
313
314
		assertEquals(3, fileManager.getSize());
292
	}
315
	}
293
316
294
	public void XXXtestTbrItem() throws Exception {
317
	public void testTbrItem() throws Exception {
295
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
318
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
296
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
319
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
297
		menuBar.setElementId("org.eclipse.ui.main.menu");
320
		menuBar.setElementId("org.eclipse.ui.main.menu");
Lines 326-336 Link Here
326
		wb = new E4Workbench(window, appContext);
349
		wb = new E4Workbench(window, appContext);
327
		wb.createAndRunUI(window);
350
		wb.createAndRunUI(window);
328
351
329
		// MenuRenderer renderer = getRenderer(appContext, menuBar);
352
		MenuManagerRenderer renderer = getRenderer(appContext, menuBar);
353
		MenuManager manager = renderer.getManager(menuBar);
354
		assertNotNull("failed to create menu bar manager", manager);
355
356
		assertEquals(1, manager.getSize());
357
358
		MenuManager fileManager = (MenuManager) manager.getItems()[0];
359
		MenuManager fileR = renderer.getManager(fileMenu);
360
		assertEquals(fileManager, fileR);
330
361
362
		assertEquals(2, fileManager.getSize());
331
	}
363
	}
332
364
333
	public void XXXtestInvisibleItem() throws Exception {
365
	public void testInvisibleItem() throws Exception {
334
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
366
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
335
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
367
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
336
		menuBar.setElementId("org.eclipse.ui.main.menu");
368
		menuBar.setElementId("org.eclipse.ui.main.menu");
Lines 365-375 Link Here
365
		wb = new E4Workbench(window, appContext);
397
		wb = new E4Workbench(window, appContext);
366
		wb.createAndRunUI(window);
398
		wb.createAndRunUI(window);
367
399
368
		// MenuRenderer renderer = getRenderer(appContext, menuBar);
400
		MenuManagerRenderer renderer = getRenderer(appContext, menuBar);
401
		MenuManager manager = renderer.getManager(menuBar);
402
		assertNotNull("failed to create menu bar manager", manager);
403
404
		assertEquals(1, manager.getSize());
405
406
		MenuManager fileManager = (MenuManager) manager.getItems()[0];
407
		MenuManager fileR = renderer.getManager(fileMenu);
408
		assertEquals(fileManager, fileR);
369
409
410
		assertEquals(3, fileManager.getSize());
411
412
		assertEquals(false, fileManager.getItems()[2].isVisible());
370
	}
413
	}
371
414
372
	public void XXXtestMenuContribution() throws Exception {
415
	public void testMenuContribution() throws Exception {
373
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
416
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
374
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
417
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
375
		menuBar.setElementId("org.eclipse.ui.main.menu");
418
		menuBar.setElementId("org.eclipse.ui.main.menu");
Lines 404-412 Link Here
404
		wb = new E4Workbench(window, appContext);
447
		wb = new E4Workbench(window, appContext);
405
		wb.createAndRunUI(window);
448
		wb.createAndRunUI(window);
406
449
450
		MenuManagerRenderer renderer = getRenderer(appContext, menuBar);
451
452
		MenuManager fileManager = renderer.getManager(fileMenu);
453
		assertNotNull("No file menu?", fileManager);
454
455
		assertEquals(4, fileManager.getSize());
456
457
		assertEquals("mmc.item1", fileManager.getItems()[3].getId());
407
	}
458
	}
408
459
409
	public void XXXtestWithVisible() throws Exception {
460
	public void testWithVisible() throws Exception {
410
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
461
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
411
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
462
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
412
		menuBar.setElementId("org.eclipse.ui.main.menu");
463
		menuBar.setElementId("org.eclipse.ui.main.menu");
Lines 441-449 Link Here
441
		wb = new E4Workbench(window, appContext);
492
		wb = new E4Workbench(window, appContext);
442
		wb.createAndRunUI(window);
493
		wb.createAndRunUI(window);
443
494
495
		MenuManagerRenderer renderer = getRenderer(appContext, menuBar);
496
497
		MenuManager fileManager = renderer.getManager(fileMenu);
498
		assertNotNull("No file menu?", fileManager);
499
500
		assertEquals(4, fileManager.getSize());
501
502
		IContributionItem mmcItem = fileManager.getItems()[3];
503
		assertEquals("mmc.item1", mmcItem.getId());
504
		assertEquals("before the first show, we have no context to evaluate",
505
				true, mmcItem.isVisible());
506
507
		MenuManager manager = renderer.getManager(menuBar);
508
		manager.updateAll(true);
509
		Menu fileWidget = fileManager.getMenu();
510
		assertNotNull(fileWidget);
511
512
		Event show = new Event();
513
		show.widget = fileWidget;
514
		show.type = SWT.Show;
515
516
		Event hide = new Event();
517
		hide.widget = fileWidget;
518
		hide.type = SWT.Hide;
519
520
		fileWidget.notifyListeners(SWT.Show, show);
521
522
		assertEquals("after the first show, it should not be visible", false,
523
				mmcItem.isVisible());
524
525
		fileWidget.notifyListeners(SWT.Hide, hide);
526
527
		appContext.set("mmc1", Boolean.TRUE);
528
529
		assertEquals("Change should not show up until next show", false,
530
				mmcItem.isVisible());
531
532
		fileWidget.notifyListeners(SWT.Show, show);
533
534
		assertEquals(true, mmcItem.isVisible());
535
536
		fileWidget.notifyListeners(SWT.Hide, hide);
537
538
		appContext.remove("mmc1");
539
540
		fileWidget.notifyListeners(SWT.Show, show);
541
542
		assertEquals(false, mmcItem.isVisible());
543
544
		fileWidget.notifyListeners(SWT.Hide, hide);
444
	}
545
	}
445
546
446
	public void XXXtestMenuBarVisibility() throws Exception {
547
	public void testMenuBarVisibility() throws Exception {
447
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
548
		MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
448
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
549
		MMenu menuBar = MenuFactoryImpl.eINSTANCE.createMenu();
449
		menuBar.setElementId("org.eclipse.ui.main.menu");
550
		menuBar.setElementId("org.eclipse.ui.main.menu");
Lines 478-483 Link Here
478
		wb = new E4Workbench(window, appContext);
579
		wb = new E4Workbench(window, appContext);
479
		wb.createAndRunUI(window);
580
		wb.createAndRunUI(window);
480
581
582
		MenuManagerRenderer renderer = getRenderer(appContext, menuBar);
583
		MenuManager manager = renderer.getManager(menuBar);
584
		manager.updateAll(true);
585
586
		assertEquals(2, manager.getSize());
587
588
		MenuManager vanishManager = (MenuManager) manager.getItems()[1];
589
		assertEquals("vanish", vanishManager.getId());
590
591
		assertFalse(vanishManager.isVisible());
592
		assertNull(vanishManager.getMenu());
593
594
		appContext.set("mmc1", Boolean.TRUE);
595
596
		assertTrue(vanishManager.isVisible());
597
		assertNotNull(vanishManager.getMenu());
598
599
		appContext.remove("mmc1");
600
601
		assertFalse(vanishManager.isVisible());
602
		Menu vanishMenu = vanishManager.getMenu();
603
		if (vanishMenu != null) {
604
			assertTrue(vanishMenu.isDisposed());
605
		}
606
607
		appContext.set("mmc1", Boolean.TRUE);
608
609
		assertTrue(vanishManager.isVisible());
610
		assertNotNull(vanishManager.getMenu());
611
		assertFalse(vanishManager.getMenu().isDisposed());
481
	}
612
	}
482
613
483
	private MMenuContribution createContribution(boolean withVisibleWhen) {
614
	private MMenuContribution createContribution(boolean withVisibleWhen) {
Lines 537-547 Link Here
537
		application.getMenuContributions().add(mmc);
668
		application.getMenuContributions().add(mmc);
538
	}
669
	}
539
670
540
	MenuRenderer getRenderer(IEclipseContext context, MUIElement element) {
671
	private MenuManagerRenderer getRenderer(IEclipseContext context,
672
			MUIElement element) {
541
		IRendererFactory rendererFactory = context.get(IRendererFactory.class);
673
		IRendererFactory rendererFactory = context.get(IRendererFactory.class);
542
		AbstractPartRenderer renderer = rendererFactory.getRenderer(element,
674
		AbstractPartRenderer renderer = rendererFactory.getRenderer(element,
543
				null);
675
				null);
544
		assertEquals(MenuRenderer.class, renderer.getClass());
676
		assertEquals(MenuManagerRenderer.class, renderer.getClass());
545
		return (MenuRenderer) renderer;
677
		return (MenuManagerRenderer) renderer;
546
	}
678
	}
547
}
679
}
(-)src/org/eclipse/e4/ui/tests/workbench/MWindowTest.java (+3 lines)
Lines 30-35 Link Here
30
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
30
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
31
import org.eclipse.e4.ui.services.IServiceConstants;
31
import org.eclipse.e4.ui.services.IServiceConstants;
32
import org.eclipse.e4.ui.widgets.CTabFolder;
32
import org.eclipse.e4.ui.widgets.CTabFolder;
33
import org.eclipse.jface.action.MenuManager;
33
import org.eclipse.swt.SWT;
34
import org.eclipse.swt.SWT;
34
import org.eclipse.swt.graphics.Rectangle;
35
import org.eclipse.swt.graphics.Rectangle;
35
import org.eclipse.swt.widgets.Composite;
36
import org.eclipse.swt.widgets.Composite;
Lines 230-235 Link Here
230
231
231
		wb = new E4Workbench(application, appContext);
232
		wb = new E4Workbench(application, appContext);
232
		wb.createAndRunUI(window);
233
		wb.createAndRunUI(window);
234
		((MenuManager) ((Widget) window.getMainMenu().getWidget()).getData())
235
				.updateAll(true);
233
236
234
		Widget topWidget = (Widget) window.getWidget();
237
		Widget topWidget = (Widget) window.getWidget();
235
		assertNotNull(topWidget);
238
		assertNotNull(topWidget);
(-)src/org/eclipse/e4/ui/internal/workbench/ContributionsAnalyzer.java (-1 / +1 lines)
Lines 176-182 Link Here
176
		return isVisible((MCoreExpression) contribution.getVisibleWhen(), eContext);
176
		return isVisible((MCoreExpression) contribution.getVisibleWhen(), eContext);
177
	}
177
	}
178
178
179
	static boolean isVisible(MCoreExpression exp, ExpressionContext eContext) {
179
	public static boolean isVisible(MCoreExpression exp, ExpressionContext eContext) {
180
		Expression ref = null;
180
		Expression ref = null;
181
		if (exp.getCoreExpression() instanceof Expression) {
181
		if (exp.getCoreExpression() instanceof Expression) {
182
			ref = (Expression) exp.getCoreExpression();
182
			ref = (Expression) exp.getCoreExpression();
(-)src/org/eclipse/e4/ui/workbench/UIEvents.java (+6 lines)
Lines 219-224 Link Here
219
219
220
	public static interface UIElement {
220
	public static interface UIElement {
221
		public static final String TOPIC = UITopicBase + "/ui/UIElement"; //$NON-NLS-1$
221
		public static final String TOPIC = UITopicBase + "/ui/UIElement"; //$NON-NLS-1$
222
		public static final String ACCESSIBILITYPHRASE = "accessibilityPhrase"; //$NON-NLS-1$
222
		public static final String CONTAINERDATA = "containerData"; //$NON-NLS-1$
223
		public static final String CONTAINERDATA = "containerData"; //$NON-NLS-1$
223
		public static final String CURSHAREDREF = "curSharedRef"; //$NON-NLS-1$
224
		public static final String CURSHAREDREF = "curSharedRef"; //$NON-NLS-1$
224
		public static final String ONTOP = "onTop"; //$NON-NLS-1$
225
		public static final String ONTOP = "onTop"; //$NON-NLS-1$
Lines 272-277 Link Here
272
		public static final String MNEMONICS = "mnemonics"; //$NON-NLS-1$
273
		public static final String MNEMONICS = "mnemonics"; //$NON-NLS-1$
273
	}
274
	}
274
275
276
	public static interface OpaqueMenuItem {
277
		public static final String TOPIC = UITopicBase + "/menu/OpaqueMenuItem"; //$NON-NLS-1$
278
		public static final String OPAQUEITEM = "opaqueItem"; //$NON-NLS-1$
279
	}
280
275
	public static interface RenderedMenu {
281
	public static interface RenderedMenu {
276
		public static final String TOPIC = UITopicBase + "/menu/RenderedMenu"; //$NON-NLS-1$
282
		public static final String TOPIC = UITopicBase + "/menu/RenderedMenu"; //$NON-NLS-1$
277
		public static final String CONTRIBUTIONMANAGER = "contributionManager"; //$NON-NLS-1$
283
		public static final String CONTRIBUTIONMANAGER = "contributionManager"; //$NON-NLS-1$
(-)src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java (-88 / +226 lines)
Lines 25-33 Link Here
25
import org.eclipse.e4.core.services.events.IEventBroker;
25
import org.eclipse.e4.core.services.events.IEventBroker;
26
import org.eclipse.e4.core.services.log.Logger;
26
import org.eclipse.e4.core.services.log.Logger;
27
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
27
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
28
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
29
import org.eclipse.e4.ui.model.application.MApplication;
28
import org.eclipse.e4.ui.model.application.MApplication;
30
import org.eclipse.e4.ui.model.application.ui.MContext;
29
import org.eclipse.e4.ui.model.application.ui.MCoreExpression;
31
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
30
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
32
import org.eclipse.e4.ui.model.application.ui.MUIElement;
31
import org.eclipse.e4.ui.model.application.ui.MUIElement;
33
import org.eclipse.e4.ui.model.application.ui.MUILabel;
32
import org.eclipse.e4.ui.model.application.ui.MUILabel;
Lines 39-45 Link Here
39
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
38
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
40
import org.eclipse.e4.ui.model.application.ui.menu.MMenuItem;
39
import org.eclipse.e4.ui.model.application.ui.menu.MMenuItem;
41
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
40
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
41
import org.eclipse.e4.ui.model.application.ui.menu.MOpaqueMenu;
42
import org.eclipse.e4.ui.model.application.ui.menu.MOpaqueMenuItem;
42
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
43
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
44
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
43
import org.eclipse.e4.ui.workbench.IResourceUtilities;
45
import org.eclipse.e4.ui.workbench.IResourceUtilities;
44
import org.eclipse.e4.ui.workbench.UIEvents;
46
import org.eclipse.e4.ui.workbench.UIEvents;
45
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
47
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
Lines 48-64 Link Here
48
import org.eclipse.emf.ecore.EObject;
50
import org.eclipse.emf.ecore.EObject;
49
import org.eclipse.emf.ecore.util.EcoreUtil;
51
import org.eclipse.emf.ecore.util.EcoreUtil;
50
import org.eclipse.jface.action.AbstractGroupMarker;
52
import org.eclipse.jface.action.AbstractGroupMarker;
53
import org.eclipse.jface.action.ContributionItem;
51
import org.eclipse.jface.action.GroupMarker;
54
import org.eclipse.jface.action.GroupMarker;
52
import org.eclipse.jface.action.IContributionItem;
55
import org.eclipse.jface.action.IContributionItem;
53
import org.eclipse.jface.action.IMenuListener;
54
import org.eclipse.jface.action.IMenuManager;
55
import org.eclipse.jface.action.MenuManager;
56
import org.eclipse.jface.action.MenuManager;
56
import org.eclipse.jface.action.Separator;
57
import org.eclipse.jface.action.Separator;
57
import org.eclipse.jface.resource.ImageDescriptor;
58
import org.eclipse.jface.resource.ImageDescriptor;
59
import org.eclipse.swt.SWT;
58
import org.eclipse.swt.events.DisposeEvent;
60
import org.eclipse.swt.events.DisposeEvent;
59
import org.eclipse.swt.events.DisposeListener;
61
import org.eclipse.swt.events.DisposeListener;
60
import org.eclipse.swt.widgets.Control;
62
import org.eclipse.swt.widgets.Control;
61
import org.eclipse.swt.widgets.Decorations;
63
import org.eclipse.swt.widgets.Decorations;
64
import org.eclipse.swt.widgets.Display;
62
import org.eclipse.swt.widgets.Menu;
65
import org.eclipse.swt.widgets.Menu;
63
import org.osgi.service.event.Event;
66
import org.osgi.service.event.Event;
64
import org.osgi.service.event.EventHandler;
67
import org.osgi.service.event.EventHandler;
Lines 72-78 Link Here
72
	private Map<MMenu, MenuManager> modelToManager = new HashMap<MMenu, MenuManager>();
75
	private Map<MMenu, MenuManager> modelToManager = new HashMap<MMenu, MenuManager>();
73
	private Map<MenuManager, MMenu> managerToModel = new HashMap<MenuManager, MMenu>();
76
	private Map<MenuManager, MMenu> managerToModel = new HashMap<MenuManager, MMenu>();
74
77
75
	private Map<MMenuItem, IContributionItem> modelToContribution = new HashMap<MMenuItem, IContributionItem>();
78
	private Map<MMenuElement, IContributionItem> modelToContribution = new HashMap<MMenuElement, IContributionItem>();
79
	private Map<IContributionItem, MMenuElement> contributionToModel = new HashMap<IContributionItem, MMenuElement>();
76
80
77
	private Map<MMenuElement, ContributionRecord> modelContributionToRecord = new HashMap<MMenuElement, ContributionRecord>();
81
	private Map<MMenuElement, ContributionRecord> modelContributionToRecord = new HashMap<MMenuElement, ContributionRecord>();
78
82
Lines 126-133 Link Here
126
							modelProcessSwitch(parent, itemModel);
130
							modelProcessSwitch(parent, itemModel);
127
						}
131
						}
128
					} else {
132
					} else {
129
						IContributionItem ici = modelToContribution
133
						IContributionItem ici = getContribution(itemModel);
130
								.remove(itemModel);
134
						clearModelToContribution(itemModel, ici);
131
						if (ici != null && parent != null) {
135
						if (ici != null && parent != null) {
132
							parent.remove(ici);
136
							parent.remove(ici);
133
						}
137
						}
Lines 145-157 Link Here
145
						return;
149
						return;
146
					}
150
					}
147
					manager.setVisible(menuModel.isVisible());
151
					manager.setVisible(menuModel.isVisible());
152
					if (manager.getParent() != null) {
153
						manager.getParent().markDirty();
154
					}
148
				} else if (element instanceof MMenuElement) {
155
				} else if (element instanceof MMenuElement) {
149
					MMenuElement itemModel = (MMenuElement) element;
156
					MMenuElement itemModel = (MMenuElement) element;
150
					IContributionItem ici = getContribution(itemModel);
157
					Object obj = getContribution(itemModel);
151
					if (ici == null) {
158
					if (!(obj instanceof ContributionItem)) {
152
						return;
159
						return;
153
					}
160
					}
154
					ici.setVisible(itemModel.isVisible());
161
					ContributionItem item = (ContributionItem) obj;
162
					item.setVisible(itemModel.isVisible());
163
					if (item.getParent() != null) {
164
						item.getParent().markDirty();
165
					}
155
				}
166
				}
156
			}
167
			}
157
		}
168
		}
Lines 165-171 Link Here
165
176
166
			MMenuItem itemModel = (MMenuItem) event
177
			MMenuItem itemModel = (MMenuItem) event
167
					.getProperty(UIEvents.EventTags.ELEMENT);
178
					.getProperty(UIEvents.EventTags.ELEMENT);
168
			IContributionItem ici = modelToContribution.get(itemModel);
179
			IContributionItem ici = getContribution(itemModel);
169
			if (ici != null) {
180
			if (ici != null) {
170
				ici.update();
181
				ici.update();
171
			}
182
			}
Lines 180-229 Link Here
180
191
181
			MMenuItem itemModel = (MMenuItem) event
192
			MMenuItem itemModel = (MMenuItem) event
182
					.getProperty(UIEvents.EventTags.ELEMENT);
193
					.getProperty(UIEvents.EventTags.ELEMENT);
183
			IContributionItem ici = modelToContribution.get(itemModel);
194
			IContributionItem ici = getContribution(itemModel);
184
			if (ici != null) {
195
			if (ici != null) {
185
				ici.update();
196
				ici.update();
186
			}
197
			}
187
		}
198
		}
188
	};
199
	};
189
200
190
	private IMenuListener visibilityCalculationListener = new IMenuListener() {
201
	private MenuManagerRendererFilter rendererFilter;
191
		public void menuAboutToShow(IMenuManager manager) {
192
			MenuManager menuManager = (MenuManager) manager;
193
			if (menuManager.getMenu() == null) {
194
				return;
195
			}
196
			MMenu menuModel = getMenuModel(menuManager);
197
			if (menuModel == null) {
198
				Menu menu = menuManager.getMenu();
199
				Object obj = menu.getData(AbstractPartRenderer.OWNING_ME);
200
				if (obj == null && menu.getParentItem() != null) {
201
					obj = menu.getParentItem().getData(
202
							AbstractPartRenderer.OWNING_ME);
203
				}
204
				if (!(obj instanceof MMenu)) {
205
					return;
206
				}
207
				menuModel = (MMenu) obj;
208
			} else if (menuModel.getWidget() == null) {
209
				bindWidget(menuModel, menuManager.getMenu());
210
			}
211
			final IEclipseContext evalContext;
212
			if (menuModel instanceof MContext) {
213
				evalContext = ((MContext) menuModel).getContext();
214
			} else {
215
				evalContext = modelService.getContainingContext(menuModel);
216
			}
217
			HashSet<ContributionRecord> records = new HashSet<ContributionRecord>();
218
			for (MMenuElement element : menuModel.getChildren()) {
219
				ContributionRecord record = modelContributionToRecord
220
						.get(element);
221
				if (record != null && records.add(record)) {
222
					record.updateVisibility(evalContext);
223
				}
224
			}
225
		}
226
	};
227
202
228
	@PostConstruct
203
	@PostConstruct
229
	public void init() {
204
	public void init() {
Lines 237-242 Link Here
237
		eventBroker.subscribe(UIEvents.buildTopic(UIEvents.UIElement.TOPIC),
212
		eventBroker.subscribe(UIEvents.buildTopic(UIEvents.UIElement.TOPIC),
238
				toBeRenderedUpdater);
213
				toBeRenderedUpdater);
239
214
215
		context.set(MenuManagerRenderer.class, this);
216
		Display display = context.get(Display.class);
217
		rendererFilter = ContextInjectionFactory.make(
218
				MenuManagerRendererFilter.class, context);
219
		display.addFilter(SWT.Show, rendererFilter);
220
		display.addFilter(SWT.Hide, rendererFilter);
221
		display.addFilter(SWT.Dispose, rendererFilter);
222
		context.set(MenuManagerRendererFilter.class, rendererFilter);
223
240
	}
224
	}
241
225
242
	@PreDestroy
226
	@PreDestroy
Lines 245-250 Link Here
245
		eventBroker.unsubscribe(selectionUpdater);
229
		eventBroker.unsubscribe(selectionUpdater);
246
		eventBroker.unsubscribe(enabledUpdater);
230
		eventBroker.unsubscribe(enabledUpdater);
247
		eventBroker.unsubscribe(toBeRenderedUpdater);
231
		eventBroker.unsubscribe(toBeRenderedUpdater);
232
233
		context.remove(MenuManagerRendererFilter.class);
234
		Display display = context.get(Display.class);
235
		if (display != null && !display.isDisposed() && rendererFilter != null) {
236
			display.removeFilter(SWT.Show, rendererFilter);
237
			display.removeFilter(SWT.Hide, rendererFilter);
238
			display.removeFilter(SWT.Dispose, rendererFilter);
239
		}
240
		if (rendererFilter != null) {
241
			ContextInjectionFactory.uninject(rendererFilter, context);
242
			rendererFilter = null;
243
		}
244
		context.remove(MenuManagerRenderer.class);
248
	}
245
	}
249
246
250
	/*
247
	/*
Lines 261-310 Link Here
261
258
262
		final MMenu menuModel = (MMenu) element;
259
		final MMenu menuModel = (MMenu) element;
263
		Menu newMenu = null;
260
		Menu newMenu = null;
261
		MenuManager menuManager = null;
264
		boolean menuBar = false;
262
		boolean menuBar = false;
265
263
266
		if (parent instanceof Decorations) {
264
		if (parent instanceof Decorations) {
267
			MUIElement container = (MUIElement) ((EObject) element)
265
			MUIElement container = (MUIElement) ((EObject) element)
268
					.eContainer();
266
					.eContainer();
269
			if (container instanceof MWindow) {
267
			if (container instanceof MWindow) {
270
				MenuManager menuBarManager = getManager(menuModel);
268
				menuManager = getManager(menuModel);
271
				if (menuBarManager == null) {
269
				if (menuManager == null) {
272
					menuBarManager = new MenuManager(NO_LABEL,
270
					menuManager = new MenuManager(NO_LABEL,
273
							menuModel.getElementId());
271
							menuModel.getElementId());
274
					linkModelToManager(menuModel, menuBarManager);
272
					linkModelToManager(menuModel, menuManager);
275
				}
273
				}
276
				newMenu = menuBarManager.createMenuBar((Decorations) parent);
274
				newMenu = menuManager.createMenuBar((Decorations) parent);
277
				((Decorations) parent).setMenuBar(newMenu);
275
				((Decorations) parent).setMenuBar(newMenu);
278
				newMenu.setData(menuBarManager);
276
				newMenu.setData(menuManager);
279
				menuBar = true;
277
				menuBar = true;
280
			} else {
278
			} else {
281
				MenuManager popupManager = getManager(menuModel);
279
				menuManager = getManager(menuModel);
282
				if (popupManager == null) {
280
				if (menuManager == null) {
283
					popupManager = new MenuManager(NO_LABEL,
281
					menuManager = new MenuManager(NO_LABEL,
284
							menuModel.getElementId());
282
							menuModel.getElementId());
285
					linkModelToManager(menuModel, popupManager);
283
					linkModelToManager(menuModel, menuManager);
286
				}
284
				}
287
				newMenu = popupManager.createContextMenu((Control) parent);
285
				newMenu = menuManager.createContextMenu((Control) parent);
288
				((Control) parent).setMenu(newMenu);
286
				// we can't be sure this is the correct parent.
289
				newMenu.setData(popupManager);
287
				// ((Control) parent).setMenu(newMenu);
288
				newMenu.setData(menuManager);
290
			}
289
			}
291
		} else if (parent instanceof Menu) {
290
		} else if (parent instanceof Menu) {
292
			// Object data = ((Menu) parent).getData();
291
			// Object data = ((Menu) parent).getData();
293
			logger.debug(new Exception(), "Trying to render a sub menu " //$NON-NLS-1$
292
			logger.debug(new Exception(), "Trying to render a sub menu " //$NON-NLS-1$
294
					+ menuModel + "\n\t" + parent); //$NON-NLS-1$
293
					+ menuModel + "\n\t" + parent); //$NON-NLS-1$
294
			return null;
295
295
296
		} else if (parent instanceof Control) {
296
		} else if (parent instanceof Control) {
297
			MenuManager popupManager = getManager(menuModel);
297
			menuManager = getManager(menuModel);
298
			if (popupManager == null) {
298
			if (menuManager == null) {
299
				popupManager = new MenuManager(NO_LABEL,
299
				menuManager = new MenuManager(NO_LABEL,
300
						menuModel.getElementId());
300
						menuModel.getElementId());
301
				linkModelToManager(menuModel, popupManager);
301
				linkModelToManager(menuModel, menuManager);
302
			}
302
			}
303
			newMenu = popupManager.createContextMenu((Control) parent);
303
			newMenu = menuManager.createContextMenu((Control) parent);
304
			((Control) parent).setMenu(newMenu);
304
			// we can't be sure this is the correct parent.
305
			newMenu.setData(popupManager);
305
			// ((Control) parent).setMenu(newMenu);
306
			newMenu.setData(menuManager);
307
		}
308
		if (!menuManager.getRemoveAllWhenShown()) {
309
			processContributions(menuModel, menuBar);
306
		}
310
		}
307
		processContributions(menuModel, menuBar);
308
		if (newMenu != null) {
311
		if (newMenu != null) {
309
			newMenu.addDisposeListener(new DisposeListener() {
312
			newMenu.addDisposeListener(new DisposeListener() {
310
				public void widgetDisposed(DisposeEvent e) {
313
				public void widgetDisposed(DisposeEvent e) {
Lines 318-324 Link Here
318
	/**
321
	/**
319
	 * @param menuModel
322
	 * @param menuModel
320
	 */
323
	 */
321
	protected void cleanUp(MMenu menuModel) {
324
	public void cleanUp(MMenu menuModel) {
322
		Collection<ContributionRecord> vals = modelContributionToRecord
325
		Collection<ContributionRecord> vals = modelContributionToRecord
323
				.values();
326
				.values();
324
		for (ContributionRecord record : vals
327
		for (ContributionRecord record : vals
Lines 336-343 Link Here
336
							copyManager.dispose();
339
							copyManager.dispose();
337
						}
340
						}
338
					} else {
341
					} else {
339
						IContributionItem ici = modelToContribution
342
						IContributionItem ici = getContribution(copy);
340
								.remove(copy);
343
						clearModelToContribution(copy, ici);
341
						if (ici != null) {
344
						if (ici != null) {
342
							record.manager.remove(ici);
345
							record.manager.remove(ici);
343
						}
346
						}
Lines 352-358 Link Here
352
	 * @param menuModel
355
	 * @param menuModel
353
	 * @param menuBar
356
	 * @param menuBar
354
	 */
357
	 */
355
	private void processContributions(MMenu menuModel, boolean menuBar) {
358
	public void processContributions(MMenu menuModel, boolean menuBar) {
356
		final ArrayList<MMenuContribution> toContribute = new ArrayList<MMenuContribution>();
359
		final ArrayList<MMenuContribution> toContribute = new ArrayList<MMenuContribution>();
357
		ContributionsAnalyzer.XXXgatherMenuContributions(menuModel,
360
		ContributionsAnalyzer.XXXgatherMenuContributions(menuModel,
358
				application.getMenuContributions(), menuModel.getElementId(),
361
				application.getMenuContributions(), menuModel.getElementId(),
Lines 500-506 Link Here
500
			boolean isVisible = ContributionsAnalyzer.isVisible(
503
			boolean isVisible = ContributionsAnalyzer.isVisible(
501
					menuContribution, exprContext);
504
					menuContribution, exprContext);
502
			for (MMenuElement item : generatedElements) {
505
			for (MMenuElement item : generatedElements) {
503
				item.setVisible(isVisible);
506
				if (isVisible && item.getVisibleWhen() != null) {
507
					MenuManagerRenderer.updateVisibility(manager, item,
508
							exprContext);
509
				} else {
510
					item.setVisible(isVisible);
511
				}
504
			}
512
			}
505
			manager.markDirty();
513
			manager.markDirty();
506
		}
514
		}
Lines 564-576 Link Here
564
	 * @param menuModel
572
	 * @param menuModel
565
	 */
573
	 */
566
	private void processMenu(MenuManager parentManager, MMenu menuModel) {
574
	private void processMenu(MenuManager parentManager, MMenu menuModel) {
567
		String menuText = getText(menuModel);
575
		MenuManager menuManager = getManager(menuModel);
568
		ImageDescriptor desc = getImageDescriptor(menuModel);
576
		if (menuManager == null) {
569
		MenuManager menuManager = new MenuManager(menuText, desc,
577
			String menuText = getText(menuModel);
570
				menuModel.getElementId());
578
			ImageDescriptor desc = getImageDescriptor(menuModel);
571
		linkModelToManager(menuModel, menuManager);
579
			menuManager = new MenuManager(menuText, desc,
572
		menuManager.setVisible(menuModel.isVisible());
580
					menuModel.getElementId());
573
		parentManager.add(menuManager);
581
			linkModelToManager(menuModel, menuManager);
582
			menuManager.setVisible(menuModel.isVisible());
583
			parentManager.add(menuManager);
584
		}
574
		processContributions(menuModel, false);
585
		processContributions(menuModel, false);
575
		List<MMenuElement> parts = menuModel.getChildren();
586
		List<MMenuElement> parts = menuModel.getChildren();
576
		if (parts != null) {
587
		if (parts != null) {
Lines 600-605 Link Here
600
		} else if (childME instanceof MMenuSeparator) {
611
		} else if (childME instanceof MMenuSeparator) {
601
			MMenuSeparator sep = (MMenuSeparator) childME;
612
			MMenuSeparator sep = (MMenuSeparator) childME;
602
			processSeparator(menuManager, sep);
613
			processSeparator(menuManager, sep);
614
		} else if (childME instanceof MOpaqueMenu) {
615
			// I'm not sure what to do here.
603
		} else if (childME instanceof MMenu) {
616
		} else if (childME instanceof MMenu) {
604
			MMenu itemModel = (MMenu) childME;
617
			MMenu itemModel = (MMenu) childME;
605
			processMenu(menuManager, itemModel);
618
			processMenu(menuManager, itemModel);
Lines 632-644 Link Here
632
	 */
645
	 */
633
	void processDirectItem(MenuManager parentManager,
646
	void processDirectItem(MenuManager parentManager,
634
			MDirectMenuItem itemModel, String id) {
647
			MDirectMenuItem itemModel, String id) {
648
		IContributionItem ici = getContribution(itemModel);
649
		if (ici != null) {
650
			return;
651
		}
635
		final IEclipseContext lclContext = getContext(itemModel);
652
		final IEclipseContext lclContext = getContext(itemModel);
636
		DirectContributionItem ci = ContextInjectionFactory.make(
653
		DirectContributionItem ci = ContextInjectionFactory.make(
637
				DirectContributionItem.class, lclContext);
654
				DirectContributionItem.class, lclContext);
638
		ci.setModel(itemModel);
655
		ci.setModel(itemModel);
639
		ci.setVisible(itemModel.isVisible());
656
		ci.setVisible(itemModel.isVisible());
640
		parentManager.add(ci);
657
		parentManager.add(ci);
641
		modelToContribution.put(itemModel, ci);
658
		linkModelToContribution(itemModel, ci);
642
	}
659
	}
643
660
644
	/**
661
	/**
Lines 647-659 Link Here
647
	 */
664
	 */
648
	void processHandledItem(MenuManager parentManager,
665
	void processHandledItem(MenuManager parentManager,
649
			MHandledMenuItem itemModel) {
666
			MHandledMenuItem itemModel) {
667
		IContributionItem ici = getContribution(itemModel);
668
		if (ici != null) {
669
			return;
670
		}
650
		final IEclipseContext lclContext = getContext(itemModel);
671
		final IEclipseContext lclContext = getContext(itemModel);
651
		HandledContributionItem ci = ContextInjectionFactory.make(
672
		HandledContributionItem ci = ContextInjectionFactory.make(
652
				HandledContributionItem.class, lclContext);
673
				HandledContributionItem.class, lclContext);
653
		ci.setModel(itemModel);
674
		ci.setModel(itemModel);
654
		ci.setVisible(itemModel.isVisible());
675
		ci.setVisible(itemModel.isVisible());
655
		parentManager.add(ci);
676
		parentManager.add(ci);
656
		modelToContribution.put(itemModel, ci);
677
		linkModelToContribution(itemModel, ci);
657
	}
678
	}
658
679
659
	private String getText(MMenu menuModel) {
680
	private String getText(MMenu menuModel) {
Lines 686-703 Link Here
686
	public void linkModelToManager(MMenu model, MenuManager manager) {
707
	public void linkModelToManager(MMenu model, MenuManager manager) {
687
		modelToManager.put(model, manager);
708
		modelToManager.put(model, manager);
688
		managerToModel.put(manager, model);
709
		managerToModel.put(manager, model);
689
		manager.addMenuListener(visibilityCalculationListener);
690
	}
710
	}
691
711
692
	public void clearModelToManager(MMenu model, MenuManager manager) {
712
	public void clearModelToManager(MMenu model, MenuManager manager) {
693
		modelToManager.remove(model);
713
		modelToManager.remove(model);
694
		managerToModel.remove(manager);
714
		managerToModel.remove(manager);
695
		if (manager != null) {
696
			manager.removeMenuListener(visibilityCalculationListener);
697
		}
698
	}
715
	}
699
716
700
	public IContributionItem getContribution(MMenuElement model) {
717
	public IContributionItem getContribution(MMenuElement model) {
701
		return modelToContribution.get(model);
718
		return modelToContribution.get(model);
702
	}
719
	}
720
721
	public MMenuElement getMenuElement(IContributionItem item) {
722
		return contributionToModel.get(item);
723
	}
724
725
	public void linkModelToContribution(MMenuElement model,
726
			IContributionItem item) {
727
		modelToContribution.put(model, item);
728
		contributionToModel.put(item, model);
729
	}
730
731
	public void clearModelToContribution(MMenuElement model,
732
			IContributionItem item) {
733
		modelToContribution.remove(model);
734
		contributionToModel.remove(item);
735
	}
736
737
	public ContributionRecord getContributionRecord(MMenuElement element) {
738
		return modelContributionToRecord.get(element);
739
	}
740
741
	/**
742
	 * @param menuManager
743
	 * @param menuModel
744
	 */
745
	public void reconcileManagerToModel(MenuManager menuManager, MMenu menuModel) {
746
		List<MMenuElement> modelChildren = menuModel.getChildren();
747
748
		HashSet<MOpaqueMenuItem> oldModelItems = new HashSet<MOpaqueMenuItem>();
749
		HashSet<MOpaqueMenu> oldMenus = new HashSet<MOpaqueMenu>();
750
		for (MMenuElement itemModel : modelChildren) {
751
			if (itemModel instanceof MOpaqueMenuItem) {
752
				oldModelItems.add((MOpaqueMenuItem) itemModel);
753
			} else if (itemModel instanceof MOpaqueMenu) {
754
				oldMenus.add((MOpaqueMenu) itemModel);
755
			}
756
		}
757
758
		IContributionItem[] items = menuManager.getItems();
759
		for (int src = 0, dest = 0; src < items.length; src++, dest++) {
760
			IContributionItem item = items[src];
761
			if (item instanceof MenuManager) {
762
				MenuManager childManager = (MenuManager) item;
763
				MMenu childModel = getMenuModel(childManager);
764
				if (childModel == null) {
765
					MMenu legacyModel = MenuFactoryImpl.eINSTANCE
766
							.createOpaqueMenu();
767
					legacyModel.setElementId(childManager.getId());
768
					legacyModel.setVisible(childManager.isVisible());
769
					linkModelToManager(legacyModel, childManager);
770
					modelChildren.add(dest, legacyModel);
771
				} else {
772
					if (childModel instanceof MOpaqueMenu) {
773
						oldMenus.remove(childModel);
774
					}
775
					if (modelChildren.size() > dest) {
776
						if (modelChildren.get(dest) != childModel) {
777
							modelChildren.remove(childModel);
778
							modelChildren.add(dest, childModel);
779
						}
780
					} else {
781
						modelChildren.add(childModel);
782
					}
783
				}
784
			} else {
785
				MMenuElement menuElement = getMenuElement(item);
786
				if (menuElement == null) {
787
					MOpaqueMenuItem legacyItem = MenuFactoryImpl.eINSTANCE
788
							.createOpaqueMenuItem();
789
					legacyItem.setElementId(item.getId());
790
					legacyItem.setVisible(item.isVisible());
791
					legacyItem.setOpaqueItem(item);
792
					linkModelToContribution(legacyItem, item);
793
					modelChildren.add(dest, legacyItem);
794
				} else if (menuElement instanceof MOpaqueMenuItem) {
795
					MOpaqueMenuItem legacyItem = (MOpaqueMenuItem) menuElement;
796
					oldModelItems.remove(legacyItem);
797
					if (modelChildren.size() > dest) {
798
						if (modelChildren.get(dest) != legacyItem) {
799
							modelChildren.remove(legacyItem);
800
							modelChildren.add(dest, legacyItem);
801
						}
802
					} else {
803
						modelChildren.add(legacyItem);
804
					}
805
				}
806
			}
807
		}
808
		if (!oldModelItems.isEmpty()) {
809
			modelChildren.removeAll(oldModelItems);
810
			for (MOpaqueMenuItem model : oldModelItems) {
811
				clearModelToContribution(model,
812
						(IContributionItem) model.getOpaqueItem());
813
			}
814
		}
815
		if (!oldMenus.isEmpty()) {
816
			modelChildren.removeAll(oldMenus);
817
			for (MOpaqueMenu oldMenu : oldMenus) {
818
				MenuManager oldManager = getManager(oldMenu);
819
				clearModelToManager(oldMenu, oldManager);
820
			}
821
		}
822
	}
823
824
	/**
825
	 * @param menuManager
826
	 * @param element
827
	 * @param evalContext
828
	 */
829
	public static void updateVisibility(MenuManager menuManager,
830
			MMenuElement element, ExpressionContext evalContext) {
831
		if (!(element.getVisibleWhen() instanceof MCoreExpression)) {
832
			return;
833
		}
834
		boolean val = ContributionsAnalyzer.isVisible(
835
				(MCoreExpression) element.getVisibleWhen(), evalContext);
836
		if (val != element.isVisible()) {
837
			element.setVisible(val);
838
			menuManager.markDirty();
839
		}
840
	}
703
}
841
}
(-)src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRendererFilter.java (+418 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 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.e4.ui.workbench.renderers.swt;
12
13
import java.lang.reflect.InvocationTargetException;
14
import java.lang.reflect.Method;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import javax.inject.Inject;
18
import org.eclipse.core.commands.ParameterizedCommand;
19
import org.eclipse.core.runtime.ISafeRunnable;
20
import org.eclipse.core.runtime.SafeRunner;
21
import org.eclipse.e4.core.commands.EHandlerService;
22
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
23
import org.eclipse.e4.core.contexts.EclipseContextFactory;
24
import org.eclipse.e4.core.contexts.IEclipseContext;
25
import org.eclipse.e4.core.di.annotations.CanExecute;
26
import org.eclipse.e4.core.services.log.Logger;
27
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
28
import org.eclipse.e4.ui.internal.workbench.swt.Policy;
29
import org.eclipse.e4.ui.internal.workbench.swt.WorkbenchSWTActivator;
30
import org.eclipse.e4.ui.model.application.ui.MContext;
31
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
32
import org.eclipse.e4.ui.model.application.ui.MUIElement;
33
import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
34
import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
35
import org.eclipse.e4.ui.model.application.ui.menu.MItem;
36
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
37
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
38
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
39
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedMenu;
40
import org.eclipse.e4.ui.workbench.modeling.EModelService;
41
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
42
import org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer.ContributionRecord;
43
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
44
import org.eclipse.jface.action.MenuManager;
45
import org.eclipse.swt.SWT;
46
import org.eclipse.swt.widgets.Event;
47
import org.eclipse.swt.widgets.Listener;
48
import org.eclipse.swt.widgets.Menu;
49
import org.eclipse.swt.widgets.Widget;
50
51
public class MenuManagerRendererFilter implements Listener {
52
	public static final String NUL_MENU_ITEM = "(None Applicable)"; //$NON-NLS-1$
53
54
	private static final String TMP_ORIGINAL_CONTEXT = "MenuServiceFilter.original.context"; //$NON-NLS-1$
55
56
	private static void trace(String msg, Widget menu, MMenu menuModel) {
57
		WorkbenchSWTActivator.trace(Policy.MENUS, msg + ": " + menu + ": " //$NON-NLS-1$ //$NON-NLS-2$
58
				+ menuModel, null);
59
	}
60
61
	private static Method aboutToShow;
62
63
	private static Method aboutToHide;
64
65
	public static Method getAboutToShow() {
66
		if (aboutToShow == null) {
67
			try {
68
				aboutToShow = MenuManager.class
69
						.getDeclaredMethod("handleAboutToShow"); //$NON-NLS-1$
70
				aboutToShow.setAccessible(true);
71
			} catch (SecurityException e) {
72
				// TODO Auto-generated catch block
73
				e.printStackTrace();
74
			} catch (NoSuchMethodException e) {
75
				// TODO Auto-generated catch block
76
				e.printStackTrace();
77
			}
78
		}
79
		return aboutToShow;
80
	}
81
82
	public static Method getAboutToHide() {
83
		if (aboutToHide == null) {
84
			try {
85
				aboutToHide = MenuManager.class
86
						.getDeclaredMethod("handleAboutToHide"); //$NON-NLS-1$
87
				aboutToHide.setAccessible(true);
88
			} catch (SecurityException e) {
89
				// TODO Auto-generated catch block
90
				e.printStackTrace();
91
			} catch (NoSuchMethodException e) {
92
				// TODO Auto-generated catch block
93
				e.printStackTrace();
94
			}
95
		}
96
		return aboutToHide;
97
	}
98
99
	@Inject
100
	private Logger logger;
101
102
	@Inject
103
	private EModelService modelService;
104
105
	@Inject
106
	private IRendererFactory rendererFactory;
107
108
	@Inject
109
	private MenuManagerRenderer renderer;
110
111
	@Inject
112
	private EHandlerService handlerService;
113
114
	private HashMap<Menu, Runnable> pendingCleanup = new HashMap<Menu, Runnable>();
115
116
	private class SafeWrapper implements ISafeRunnable {
117
		Event event;
118
119
		public void handleException(Throwable e) {
120
			if (e instanceof Error) {
121
				// errors are deadly, we shouldn't ignore these
122
				throw (Error) e;
123
			}
124
			// log exceptions otherwise
125
			if (logger != null) {
126
				logger.error(e);
127
			}
128
		}
129
130
		public void run() throws Exception {
131
			safeHandleEvent(event);
132
		}
133
	}
134
135
	private SafeWrapper safeWrapper = new SafeWrapper();
136
137
	public void handleEvent(final Event event) {
138
		// wrap the handling in a SafeRunner so that exceptions do not prevent
139
		// the menu from being shown
140
		safeWrapper.event = event;
141
		SafeRunner.run(safeWrapper);
142
	}
143
144
	private void safeHandleEvent(Event event) {
145
		if (!(event.widget instanceof Menu)) {
146
			return;
147
		}
148
		final Menu menu = (Menu) event.widget;
149
		if ((menu.getStyle() & SWT.BAR) != 0) {
150
			// don't process the menu bar, it's not fair :-)
151
			return;
152
		}
153
		if (event.type == SWT.Dispose) {
154
			trace("handleMenu.Dispose", menu, null); //$NON-NLS-1$
155
			cleanUp(menu, null, null);
156
			return;
157
		}
158
159
		// fill in all of the pieces
160
		MMenu menuModel = null;
161
		MenuManager menuManager = null;
162
		Object obj = menu.getData(AbstractPartRenderer.OWNING_ME);
163
		if (obj == null && menu.getParentItem() != null) {
164
			obj = menu.getParentItem().getData(AbstractPartRenderer.OWNING_ME);
165
			if (obj == null) {
166
				// hack because MenuManager doesn't do a setData()
167
				Object tmp = menu.getParentItem().getData();
168
				if (tmp instanceof MenuManager) {
169
					MenuManager tmpManager = (MenuManager) tmp;
170
					if (menu == tmpManager.getMenu()) {
171
						// Eureka! We found a match, by golly!
172
						menuManager = tmpManager;
173
						obj = renderer.getMenuModel(tmpManager);
174
					}
175
				}
176
			}
177
		}
178
		if (obj instanceof MMenu) {
179
			menuModel = (MMenu) obj;
180
		}
181
		if (menuManager == null && menuModel != null) {
182
			menuManager = renderer.getManager(menuModel);
183
		}
184
185
		switch (event.type) {
186
		case SWT.Show:
187
			handleShow(event, menu, menuModel, menuManager);
188
			break;
189
		case SWT.Hide:
190
			handleHide(event, menu, menuModel, menuManager);
191
			break;
192
		}
193
194
	}
195
196
	private void handleShow(final Event event, final Menu menu,
197
			MMenu menuModel, MenuManager menuManager) {
198
		if (menuModel != null && menuManager != null) {
199
			cleanUp(menu, menuModel, menuManager);
200
		}
201
		if (menuModel instanceof MPopupMenu) {
202
			showPopup(event, menu, (MPopupMenu) menuModel, menuManager);
203
		}
204
		if (menuModel != null) {
205
			showMenu(event, menu, menuModel, menuManager);
206
		} else {
207
			trace("Incorrect menu model to work with " + menuManager, menu, menuModel); //$NON-NLS-1$
208
		}
209
	}
210
211
	private void handleHide(final Event event, final Menu menu,
212
			MMenu menuModel, MenuManager menuManager) {
213
		if (menuModel instanceof MPopupMenu) {
214
			hidePopup(event, menu, (MPopupMenu) menuModel, menuManager);
215
		}
216
	}
217
218
	public void showMenu(final Event event, final Menu menu,
219
			final MMenu menuModel, MenuManager menuManager) {
220
		AbstractPartRenderer obj = rendererFactory.getRenderer(menuModel,
221
				menu.getParent());
222
		if (!(obj instanceof MenuManagerRenderer)) {
223
			trace("Not the correct renderer: " + obj, menu, menuModel); //$NON-NLS-1$
224
			return;
225
		}
226
		MenuManagerRenderer renderer = (MenuManagerRenderer) obj;
227
		if (menuModel.getWidget() == null) {
228
			renderer.bindWidget(menuModel, menuManager.getMenu());
229
		}
230
231
		Method handleAboutToShow = getAboutToShow();
232
		try {
233
			handleAboutToShow.invoke(menuManager);
234
		} catch (IllegalArgumentException e) {
235
			// TODO Auto-generated catch block
236
			e.printStackTrace();
237
		} catch (IllegalAccessException e) {
238
			// TODO Auto-generated catch block
239
			e.printStackTrace();
240
		} catch (InvocationTargetException e) {
241
			// TODO Auto-generated catch block
242
			e.printStackTrace();
243
		}
244
245
		if (!menuManager.getRemoveAllWhenShown()) {
246
			renderer.reconcileManagerToModel(menuManager, menuModel);
247
			// this will make sure all model elements are represented in the
248
			// menu itself.
249
			// double cast because we're bad people
250
			renderer.processContents((MElementContainer<MUIElement>) ((Object) menuModel));
251
		}
252
253
		final IEclipseContext evalContext;
254
		if (menuModel instanceof MContext) {
255
			evalContext = ((MContext) menuModel).getContext();
256
		} else {
257
			evalContext = modelService.getContainingContext(menuModel);
258
		}
259
		updateElementVisibility(menuModel, renderer, menuManager, evalContext,
260
				true);
261
262
		// last thing to do, kill the event and update the menu manager
263
		event.type = SWT.None;
264
		event.doit = false;
265
		menuManager.update(false);
266
	}
267
268
	/**
269
	 * @param menuModel
270
	 * @param renderer
271
	 * @param menuManager
272
	 * @param evalContext
273
	 */
274
	private void updateElementVisibility(final MMenu menuModel,
275
			MenuManagerRenderer renderer, MenuManager menuManager,
276
			final IEclipseContext evalContext, boolean recurse) {
277
		final ExpressionContext exprContext = new ExpressionContext(evalContext);
278
		HashSet<ContributionRecord> records = new HashSet<ContributionRecord>();
279
		for (MMenuElement element : menuModel.getChildren()) {
280
			ContributionRecord record = renderer.getContributionRecord(element);
281
			if (record != null) {
282
				if (records.add(record)) {
283
					record.updateVisibility(evalContext);
284
				}
285
			} else {
286
				MenuManagerRenderer.updateVisibility(menuManager, element,
287
						exprContext);
288
			}
289
			if (recurse && element.isVisible() && element instanceof MMenu) {
290
				MMenu childMenu = (MMenu) element;
291
				MenuManager childManager = renderer.getManager(childMenu);
292
				if (childManager != null) {
293
					updateElementVisibility(childMenu, renderer, childManager,
294
							evalContext, false);
295
				}
296
			}
297
298
			if (element instanceof MHandledMenuItem) {
299
				ParameterizedCommand cmd = ((MHandledMenuItem) element)
300
						.getWbCommand();
301
				if (cmd != null) {
302
					((MHandledMenuItem) element).setEnabled(handlerService
303
							.canExecute(cmd));
304
				}
305
			} else if (element instanceof MDirectMenuItem) {
306
				MDirectMenuItem contrib = (MDirectMenuItem) element;
307
				if (contrib.getObject() != null) {
308
					IEclipseContext staticContext = EclipseContextFactory
309
							.create();
310
					staticContext.set(MItem.class, contrib);
311
					Object rc = ContextInjectionFactory.invoke(
312
							contrib.getObject(), CanExecute.class, evalContext,
313
							staticContext, Boolean.TRUE);
314
					if (rc instanceof Boolean) {
315
						contrib.setEnabled((Boolean) rc);
316
					}
317
				}
318
			}
319
		}
320
	}
321
322
	public void hidePopup(Event event, Menu menu, MPopupMenu menuModel,
323
			MenuManager menuManager) {
324
		final IEclipseContext popupContext = menuModel.getContext();
325
		final IEclipseContext originalChild = (IEclipseContext) popupContext
326
				.get(TMP_ORIGINAL_CONTEXT);
327
		popupContext.remove(TMP_ORIGINAL_CONTEXT);
328
		if (!menu.isDisposed()) {
329
			menu.getDisplay().asyncExec(new Runnable() {
330
				public void run() {
331
					if (originalChild == null) {
332
						popupContext.deactivate();
333
					} else {
334
						originalChild.activate();
335
					}
336
				}
337
			});
338
		}
339
	}
340
341
	public void showPopup(final Event event, final Menu menu,
342
			final MPopupMenu menuModel, MenuManager menuManager) {
343
		// System.err.println("showPopup: " + menuModel + "\n\t" + menu);
344
		// we need some context foolery here
345
		final IEclipseContext popupContext = menuModel.getContext();
346
		final IEclipseContext parentContext = popupContext.getParent();
347
		final IEclipseContext originalChild = parentContext.getActiveChild();
348
		popupContext.activate();
349
		popupContext.set(TMP_ORIGINAL_CONTEXT, originalChild);
350
	}
351
352
	void setEnabled(MHandledMenuItem item) {
353
		if (!item.isToBeRendered() || !item.isVisible()
354
				|| item.getWidget() == null) {
355
			return;
356
		}
357
		ParameterizedCommand cmd = item.getWbCommand();
358
		if (cmd == null) {
359
			return;
360
		}
361
		final IEclipseContext lclContext = modelService
362
				.getContainingContext(item);
363
		EHandlerService service = lclContext.get(EHandlerService.class);
364
		item.setEnabled(service.canExecute(cmd));
365
	}
366
367
	public void showRenderedMenu(final Event event, final Menu menu,
368
			final MRenderedMenu menuModel) {
369
		if (!(menuModel.getContributionManager() instanceof MenuManager)) {
370
			return;
371
		}
372
373
		MenuManager manager = (MenuManager) menuModel.getContributionManager();
374
		Method handleAboutToShow = getAboutToShow();
375
		try {
376
			handleAboutToShow.invoke(manager);
377
		} catch (IllegalArgumentException e) {
378
			// TODO Auto-generated catch block
379
			e.printStackTrace();
380
		} catch (IllegalAccessException e) {
381
			// TODO Auto-generated catch block
382
			e.printStackTrace();
383
		} catch (InvocationTargetException e) {
384
			// TODO Auto-generated catch block
385
			e.printStackTrace();
386
		}
387
388
		// if (menuModel.getChildren().size() == 1
389
		// && menuModel.getChildren().get(0) instanceof MPopupMenu) {
390
		// showPopup(event, menu, (MPopupMenu) menuModel.getChildren().get(0));
391
		// } else {
392
		// showMenu(event, menu, menuModel, null);
393
		// }
394
		event.type = SWT.None;
395
		event.doit = false;
396
	}
397
398
	public void cleanUp(final Menu menu, MMenu menuModel,
399
			MenuManager menuManager) {
400
		trace("cleanUp", menu, null); //$NON-NLS-1$
401
		if (pendingCleanup.isEmpty()) {
402
			return;
403
		}
404
		Runnable cleanUp = pendingCleanup.remove(menu);
405
		if (cleanUp != null) {
406
			trace("cleanUp.run()", menu, null); //$NON-NLS-1$
407
			cleanUp.run();
408
		}
409
	}
410
411
	public void dispose() {
412
		Menu[] keys = pendingCleanup.keySet().toArray(
413
				new Menu[pendingCleanup.size()]);
414
		for (Menu menu : keys) {
415
			cleanUp(menu, null, null);
416
		}
417
	}
418
}
(-)src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerServiceFilter.java (+182 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 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.e4.ui.workbench.renderers.swt;
12
13
import java.lang.reflect.Method;
14
import javax.inject.Inject;
15
import org.eclipse.core.runtime.ISafeRunnable;
16
import org.eclipse.core.runtime.SafeRunner;
17
import org.eclipse.e4.core.contexts.IEclipseContext;
18
import org.eclipse.e4.core.services.log.Logger;
19
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
20
import org.eclipse.e4.ui.internal.workbench.swt.Policy;
21
import org.eclipse.e4.ui.internal.workbench.swt.WorkbenchSWTActivator;
22
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
23
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
24
import org.eclipse.e4.ui.workbench.modeling.EModelService;
25
import org.eclipse.jface.action.MenuManager;
26
import org.eclipse.swt.SWT;
27
import org.eclipse.swt.widgets.Event;
28
import org.eclipse.swt.widgets.Listener;
29
import org.eclipse.swt.widgets.Menu;
30
import org.eclipse.swt.widgets.Widget;
31
32
public class MenuManagerServiceFilter implements Listener {
33
	public static final String NUL_MENU_ITEM = "(None Applicable)"; //$NON-NLS-1$
34
35
	private static final String TMP_ORIGINAL_CONTEXT = "MenuServiceFilter.original.context"; //$NON-NLS-1$
36
37
	private static void trace(String msg, Widget menu, MMenu menuModel) {
38
		WorkbenchSWTActivator.trace(Policy.MENUS, msg + ": " + menu + ": " //$NON-NLS-1$ //$NON-NLS-2$
39
				+ menuModel, null);
40
	}
41
42
	private static Method aboutToShow;
43
44
	public static Method getAboutToShow() {
45
		if (aboutToShow == null) {
46
			try {
47
				aboutToShow = MenuManager.class
48
						.getDeclaredMethod("handleAboutToShow"); //$NON-NLS-1$
49
				aboutToShow.setAccessible(true);
50
			} catch (SecurityException e) {
51
				// TODO Auto-generated catch block
52
				e.printStackTrace();
53
			} catch (NoSuchMethodException e) {
54
				// TODO Auto-generated catch block
55
				e.printStackTrace();
56
			}
57
		}
58
		return aboutToShow;
59
	}
60
61
	@Inject
62
	private Logger logger;
63
64
	@Inject
65
	EModelService modelService;
66
67
	public void handleEvent(final Event event) {
68
		// wrap the handling in a SafeRunner so that exceptions do not prevent
69
		// the menu from being shown
70
		SafeRunner.run(new ISafeRunnable() {
71
			public void handleException(Throwable e) {
72
				if (e instanceof Error) {
73
					// errors are deadly, we shouldn't ignore these
74
					throw (Error) e;
75
				} else {
76
					// log exceptions otherwise
77
					if (logger != null) {
78
						logger.error(e);
79
					}
80
				}
81
			}
82
83
			public void run() throws Exception {
84
				safeHandleEvent(event);
85
			}
86
		});
87
	}
88
89
	private void safeHandleEvent(Event event) {
90
		if (!(event.widget instanceof Menu)) {
91
			return;
92
		}
93
		final Menu menu = (Menu) event.widget;
94
		if (event.type == SWT.Dispose) {
95
			trace("handleMenu.Dispose", menu, null); //$NON-NLS-1$
96
			cleanUp(menu);
97
		}
98
		Object obj = menu.getData(AbstractPartRenderer.OWNING_ME);
99
		if (obj == null && menu.getParentItem() != null) {
100
			obj = menu.getParentItem().getData(AbstractPartRenderer.OWNING_ME);
101
		}
102
		if (obj instanceof MPopupMenu) {
103
			handleContextMenu(event, menu, (MPopupMenu) obj);
104
		} else if (obj instanceof MMenu) {
105
			handleMenu(event, menu, (MMenu) obj);
106
		}
107
	}
108
109
	private void handleMenu(final Event event, final Menu menu,
110
			final MMenu menuModel) {
111
		if ((menu.getStyle() & SWT.BAR) != 0) {
112
			// don't process the menu bar, it's not fair :-)
113
			return;
114
		}
115
		switch (event.type) {
116
		case SWT.Show:
117
			cleanUp(menu);
118
			showMenu(event, menu, menuModel);
119
			break;
120
		case SWT.Hide:
121
			// TODO we'll clean up on show
122
			break;
123
		}
124
	}
125
126
	public void showMenu(final Event event, final Menu menu,
127
			final MMenu menuModel) {
128
		// System.err.println("showMenu: " + menuModel + "\n\t" + menu);
129
	}
130
131
	private void handleContextMenu(final Event event, final Menu menu,
132
			final MPopupMenu menuModel) {
133
		switch (event.type) {
134
		case SWT.Show:
135
			cleanUp(menu);
136
			showPopup(event, menu, menuModel);
137
			break;
138
		case SWT.Hide:
139
			hidePopup(event, menu, menuModel);
140
			break;
141
		}
142
	}
143
144
	public void hidePopup(Event event, Menu menu, MPopupMenu menuModel) {
145
		// System.err.println("hidePopup: " + menuModel + "\n\t" + menu);
146
		final IEclipseContext popupContext = menuModel.getContext();
147
		final IEclipseContext originalChild = (IEclipseContext) popupContext
148
				.get(TMP_ORIGINAL_CONTEXT);
149
		popupContext.remove(TMP_ORIGINAL_CONTEXT);
150
		if (!menu.isDisposed()) {
151
			menu.getDisplay().asyncExec(new Runnable() {
152
				public void run() {
153
					if (originalChild == null) {
154
						popupContext.deactivate();
155
					} else {
156
						originalChild.activate();
157
					}
158
				}
159
			});
160
		}
161
	}
162
163
	public void showPopup(final Event event, final Menu menu,
164
			final MPopupMenu menuModel) {
165
		// System.err.println("showPopup: " + menuModel + "\n\t" + menu);
166
		// we need some context foolery here
167
		final IEclipseContext popupContext = menuModel.getContext();
168
		final IEclipseContext parentContext = popupContext.getParent();
169
		final IEclipseContext originalChild = parentContext.getActiveChild();
170
		popupContext.activate();
171
		popupContext.set(TMP_ORIGINAL_CONTEXT, originalChild);
172
173
	}
174
175
	public void cleanUp(final Menu menu) {
176
		// System.err.println("cleanUp: " + menu);
177
	}
178
179
	public void dispose() {
180
		// System.err.println("dispose");
181
	}
182
}
(-)src/org/eclipse/e4/ui/workbench/renderers/swt/MenuRenderer.java (-2 / +1 lines)
Lines 25-31 Link Here
25
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
25
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
26
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
26
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
27
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
27
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
28
import org.eclipse.e4.ui.workbench.swt.modeling.MenuServiceFilter;
29
import org.eclipse.emf.ecore.EObject;
28
import org.eclipse.emf.ecore.EObject;
30
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.events.DisposeEvent;
30
import org.eclipse.swt.events.DisposeEvent;
Lines 102-108 Link Here
102
				}
101
				}
103
				Menu menu = mi.getMenu();
102
				Menu menu = mi.getMenu();
104
				MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
103
				MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
105
				menuItem.setText(MenuServiceFilter.NUL_MENU_ITEM);
104
				menuItem.setText(MenuManagerRendererFilter.NUL_MENU_ITEM);
106
				menuItem.setEnabled(false);
105
				menuItem.setEnabled(false);
107
			}
106
			}
108
		}
107
		}
(-)src/org/eclipse/e4/ui/workbench/renderers/swt/SeparatorRenderer.java (-16 / +2 lines)
Lines 12-22 Link Here
12
12
13
import java.util.List;
13
import java.util.List;
14
import org.eclipse.e4.ui.model.application.ui.MUIElement;
14
import org.eclipse.e4.ui.model.application.ui.MUIElement;
15
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
16
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarSeparator;
15
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarSeparator;
17
import org.eclipse.swt.SWT;
16
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Menu;
19
import org.eclipse.swt.widgets.MenuItem;
20
import org.eclipse.swt.widgets.ToolBar;
17
import org.eclipse.swt.widgets.ToolBar;
21
import org.eclipse.swt.widgets.ToolItem;
18
import org.eclipse.swt.widgets.ToolItem;
22
import org.eclipse.swt.widgets.Widget;
19
import org.eclipse.swt.widgets.Widget;
Lines 41-61 Link Here
41
			return null;
38
			return null;
42
		}
39
		}
43
		if (nextVisibleChild.isVisible()
40
		if (nextVisibleChild.isVisible()
44
				&& (nextVisibleChild instanceof MMenuSeparator || nextVisibleChild instanceof MToolBarSeparator)) {
41
				&& (nextVisibleChild instanceof MToolBarSeparator)) {
45
			return null;
42
			return null;
46
		}
43
		}
47
		if (element instanceof MMenuSeparator) {
44
		if (element instanceof MToolBarSeparator) {
48
			Menu menu = null;
49
			Object widget = element.getParent().getWidget();
50
			if (widget instanceof Menu) {
51
				menu = (Menu) widget;
52
			} else if (widget instanceof MenuItem) {
53
				menu = ((MenuItem) widget).getMenu();
54
			}
55
			if (menu != null) {
56
				newSep = new MenuItem(menu, SWT.SEPARATOR, addIndex);
57
			}
58
		} else if (element instanceof MToolBarSeparator) {
59
			ToolBar tb = parent instanceof ToolBar ? (ToolBar) parent
45
			ToolBar tb = parent instanceof ToolBar ? (ToolBar) parent
60
					: (ToolBar) element.getParent().getWidget();
46
					: (ToolBar) element.getParent().getWidget();
61
			newSep = new ToolItem(tb, SWT.SEPARATOR, addIndex);
47
			newSep = new ToolItem(tb, SWT.SEPARATOR, addIndex);
(-)src/org/eclipse/e4/ui/workbench/renderers/swt/WorkbenchRendererFactory.java (-34 / +2 lines)
Lines 14-25 Link Here
14
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
14
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
15
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
15
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
16
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
16
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
17
import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
18
import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
19
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
17
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
20
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
18
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
21
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedMenu;
22
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedMenuItem;
23
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedToolBar;
19
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedToolBar;
24
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
20
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
25
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarSeparator;
21
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarSeparator;
Lines 30-37 Link Here
30
public class WorkbenchRendererFactory implements IRendererFactory {
26
public class WorkbenchRendererFactory implements IRendererFactory {
31
27
32
	private AreaRenderer areaRenderer;
28
	private AreaRenderer areaRenderer;
33
	private MenuRenderer menuRenderer;
29
	private MenuManagerRenderer menuRenderer;
34
	private HandledMenuItemRenderer handledMenuItemRenderer;
35
	private ToolBarRenderer toolbarRenderer;
30
	private ToolBarRenderer toolbarRenderer;
36
	private ToolItemRenderer toolItemRenderer;
31
	private ToolItemRenderer toolItemRenderer;
37
	private SeparatorRenderer separatorRenderer;
32
	private SeparatorRenderer separatorRenderer;
Lines 46-54 Link Here
46
	private WBWRenderer wbwRenderer;
41
	private WBWRenderer wbwRenderer;
47
42
48
	private IEclipseContext context;
43
	private IEclipseContext context;
49
	private DirectMenuItemRenderer directMenuItemRenderer;
50
	private RenderedMenuRenderer renderedMenuRenderer;
51
	private RenderedMenuItemRenderer renderedMenuItemRenderer;
52
	private RenderedToolBarRenderer renderedToolbarRenderer;
44
	private RenderedToolBarRenderer renderedToolbarRenderer;
53
45
54
	public AbstractPartRenderer getRenderer(MUIElement uiElement, Object parent) {
46
	public AbstractPartRenderer getRenderer(MUIElement uiElement, Object parent) {
Lines 64-96 Link Here
64
				initRenderer(contributedPartRenderer);
56
				initRenderer(contributedPartRenderer);
65
			}
57
			}
66
			return contributedPartRenderer;
58
			return contributedPartRenderer;
67
		} else if (uiElement instanceof MHandledMenuItem) {
68
			if (handledMenuItemRenderer == null) {
69
				handledMenuItemRenderer = new HandledMenuItemRenderer();
70
				initRenderer(handledMenuItemRenderer);
71
			}
72
			return handledMenuItemRenderer;
73
		} else if (uiElement instanceof MDirectMenuItem) {
74
			if (directMenuItemRenderer == null) {
75
				directMenuItemRenderer = new DirectMenuItemRenderer();
76
				initRenderer(directMenuItemRenderer);
77
			}
78
			return directMenuItemRenderer;
79
		} else if (uiElement instanceof MRenderedMenu) {
80
			if (renderedMenuRenderer == null) {
81
				renderedMenuRenderer = new RenderedMenuRenderer();
82
				initRenderer(renderedMenuRenderer);
83
			}
84
			return renderedMenuRenderer;
85
		} else if (uiElement instanceof MRenderedMenuItem) {
86
			if (renderedMenuItemRenderer == null) {
87
				renderedMenuItemRenderer = new RenderedMenuItemRenderer();
88
				initRenderer(renderedMenuItemRenderer);
89
			}
90
			return renderedMenuItemRenderer;
91
		} else if (uiElement instanceof MMenu) {
59
		} else if (uiElement instanceof MMenu) {
92
			if (menuRenderer == null) {
60
			if (menuRenderer == null) {
93
				menuRenderer = new MenuRenderer();
61
				menuRenderer = new MenuManagerRenderer();
94
				initRenderer(menuRenderer);
62
				initRenderer(menuRenderer);
95
			}
63
			}
96
			return menuRenderer;
64
			return menuRenderer;
(-)src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java (-24 / +13 lines)
Lines 52-57 Link Here
52
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
52
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
53
import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow;
53
import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow;
54
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
54
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
55
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
55
import org.eclipse.e4.ui.services.IStylingEngine;
56
import org.eclipse.e4.ui.services.IStylingEngine;
56
import org.eclipse.e4.ui.workbench.IPresentationEngine;
57
import org.eclipse.e4.ui.workbench.IPresentationEngine;
57
import org.eclipse.e4.ui.workbench.IResourceUtilities;
58
import org.eclipse.e4.ui.workbench.IResourceUtilities;
Lines 59-65 Link Here
59
import org.eclipse.e4.ui.workbench.UIEvents;
60
import org.eclipse.e4.ui.workbench.UIEvents;
60
import org.eclipse.e4.ui.workbench.modeling.EModelService;
61
import org.eclipse.e4.ui.workbench.modeling.EModelService;
61
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
62
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
62
import org.eclipse.e4.ui.workbench.swt.modeling.MenuServiceFilter;
63
import org.eclipse.emf.ecore.impl.EObjectImpl;
63
import org.eclipse.emf.ecore.impl.EObjectImpl;
64
import org.eclipse.equinox.app.IApplication;
64
import org.eclipse.equinox.app.IApplication;
65
import org.eclipse.equinox.app.IApplicationContext;
65
import org.eclipse.equinox.app.IApplicationContext;
Lines 91-98 Link Here
91
91
92
	IRendererFactory curFactory = null;
92
	IRendererFactory curFactory = null;
93
93
94
	MenuServiceFilter menuServiceFilter;
95
96
	org.eclipse.swt.widgets.Listener keyListener;
94
	org.eclipse.swt.widgets.Listener keyListener;
97
95
98
	// Life Cycle handlers
96
	// Life Cycle handlers
Lines 109-116 Link Here
109
						.eContainer();
107
						.eContainer();
110
			}
108
			}
111
109
110
			boolean menuChild = parent instanceof MMenu;
111
112
			// If the parent isn't displayed who cares?
112
			// If the parent isn't displayed who cares?
113
			if (parent == null || parent.getWidget() == null)
113
			if (parent == null || parent.getWidget() == null || menuChild)
114
				return;
114
				return;
115
115
116
			if (changedElement.isToBeRendered()) {
116
			if (changedElement.isToBeRendered()) {
Lines 208-216 Link Here
208
			MElementContainer<MUIElement> changedElement = (MElementContainer<MUIElement>) changedObj;
208
			MElementContainer<MUIElement> changedElement = (MElementContainer<MUIElement>) changedObj;
209
			boolean isApplication = changedObj instanceof MApplication;
209
			boolean isApplication = changedObj instanceof MApplication;
210
210
211
			boolean menuChild = changedObj instanceof MMenu;
211
			// If the parent isn't in the UI then who cares?
212
			// If the parent isn't in the UI then who cares?
212
			AbstractPartRenderer renderer = getRendererFor(changedElement);
213
			AbstractPartRenderer renderer = getRendererFor(changedElement);
213
			if (!isApplication && renderer == null)
214
			if ((!isApplication && renderer == null) || menuChild)
214
				return;
215
				return;
215
216
216
			String eventType = (String) event
217
			String eventType = (String) event
Lines 688-694 Link Here
688
689
689
	public Object run(final MApplicationElement uiRoot,
690
	public Object run(final MApplicationElement uiRoot,
690
			final IEclipseContext runContext) {
691
			final IEclipseContext runContext) {
691
		final Display display = Display.getDefault();
692
		final Display display;
693
		if (runContext.get(Display.class) != null) {
694
			display = runContext.get(Display.class);
695
		} else {
696
			display = Display.getDefault();
697
			runContext.set(Display.class, display);
698
		}
692
		Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
699
		Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
693
700
694
			public void run() {
701
			public void run() {
Lines 706-718 Link Here
706
				display.addFilter(SWT.KeyDown, keyListener);
713
				display.addFilter(SWT.KeyDown, keyListener);
707
				display.addFilter(SWT.Traverse, keyListener);
714
				display.addFilter(SWT.Traverse, keyListener);
708
715
709
				menuServiceFilter = ContextInjectionFactory.make(
710
						MenuServiceFilter.class, runContext);
711
				display.addFilter(SWT.Show, menuServiceFilter);
712
				display.addFilter(SWT.Hide, menuServiceFilter);
713
				display.addFilter(SWT.Dispose, menuServiceFilter);
714
				runContext.set(MenuServiceFilter.class, menuServiceFilter);
715
716
				// Show the initial UI
716
				// Show the initial UI
717
717
718
				// Create a 'limbo' shell (used to host controls that shouldn't
718
				// Create a 'limbo' shell (used to host controls that shouldn't
Lines 845-861 Link Here
845
	 * why this is needed we should make this safe for multiple calls
845
	 * why this is needed we should make this safe for multiple calls
846
	 */
846
	 */
847
	private void cleanUp() {
847
	private void cleanUp() {
848
		if (menuServiceFilter != null) {
849
			Display display = Display.getDefault();
850
			if (!display.isDisposed()) {
851
				display.removeFilter(SWT.Show, menuServiceFilter);
852
				display.removeFilter(SWT.Hide, menuServiceFilter);
853
				display.removeFilter(SWT.Dispose, menuServiceFilter);
854
				menuServiceFilter.dispose();
855
				menuServiceFilter = null;
856
				appContext.remove(MenuServiceFilter.class);
857
			}
858
		}
859
		if (keyListener != null) {
848
		if (keyListener != null) {
860
			Display display = Display.getDefault();
849
			Display display = Display.getDefault();
861
			if (!display.isDisposed()) {
850
			if (!display.isDisposed()) {
(-)src/org/eclipse/e4/ui/workbench/swt/modeling/MenuManagerServiceFilter.java (-193 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 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.e4.ui.workbench.swt.modeling;
12
13
import java.lang.reflect.Method;
14
import java.util.HashMap;
15
import javax.inject.Inject;
16
import org.eclipse.core.runtime.ISafeRunnable;
17
import org.eclipse.core.runtime.SafeRunner;
18
import org.eclipse.e4.core.contexts.IEclipseContext;
19
import org.eclipse.e4.core.services.log.Logger;
20
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
21
import org.eclipse.e4.ui.internal.workbench.swt.Policy;
22
import org.eclipse.e4.ui.internal.workbench.swt.WorkbenchSWTActivator;
23
import org.eclipse.e4.ui.model.application.MApplication;
24
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
25
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
26
import org.eclipse.e4.ui.workbench.IPresentationEngine;
27
import org.eclipse.e4.ui.workbench.modeling.EModelService;
28
import org.eclipse.jface.action.MenuManager;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.widgets.Event;
31
import org.eclipse.swt.widgets.Listener;
32
import org.eclipse.swt.widgets.Menu;
33
import org.eclipse.swt.widgets.Widget;
34
35
public class MenuManagerServiceFilter implements Listener {
36
	public static final String NUL_MENU_ITEM = "(None Applicable)"; //$NON-NLS-1$
37
38
	private static final String TMP_ORIGINAL_CONTEXT = "MenuServiceFilter.original.context";
39
40
	private static void trace(String msg, Widget menu, MMenu menuModel) {
41
		WorkbenchSWTActivator.trace(Policy.MENUS, msg + ": " + menu + ": "
42
				+ menuModel, null);
43
	}
44
45
	private static Method aboutToShow;
46
47
	public static Method getAboutToShow() {
48
		if (aboutToShow == null) {
49
			try {
50
				aboutToShow = MenuManager.class
51
						.getDeclaredMethod("handleAboutToShow");
52
				aboutToShow.setAccessible(true);
53
			} catch (SecurityException e) {
54
				// TODO Auto-generated catch block
55
				e.printStackTrace();
56
			} catch (NoSuchMethodException e) {
57
				// TODO Auto-generated catch block
58
				e.printStackTrace();
59
			}
60
		}
61
		return aboutToShow;
62
	}
63
64
	@Inject
65
	private MApplication application;
66
67
	@Inject
68
	private IPresentationEngine renderer;
69
70
	@Inject
71
	private Logger logger;
72
73
	@Inject
74
	EModelService modelService;
75
76
	private HashMap<Menu, Runnable> pendingCleanup = new HashMap<Menu, Runnable>();
77
78
	public void handleEvent(final Event event) {
79
		// wrap the handling in a SafeRunner so that exceptions do not prevent
80
		// the menu from being shown
81
		SafeRunner.run(new ISafeRunnable() {
82
			public void handleException(Throwable e) {
83
				if (e instanceof Error) {
84
					// errors are deadly, we shouldn't ignore these
85
					throw (Error) e;
86
				} else {
87
					// log exceptions otherwise
88
					if (logger != null) {
89
						logger.error(e);
90
					}
91
				}
92
			}
93
94
			public void run() throws Exception {
95
				safeHandleEvent(event);
96
			}
97
		});
98
	}
99
100
	private void safeHandleEvent(Event event) {
101
		if (!(event.widget instanceof Menu)) {
102
			return;
103
		}
104
		final Menu menu = (Menu) event.widget;
105
		if (event.type == SWT.Dispose) {
106
			trace("handleMenu.Dispose", menu, null);
107
			cleanUp(menu);
108
		}
109
		Object obj = menu.getData(AbstractPartRenderer.OWNING_ME);
110
		if (obj == null && menu.getParentItem() != null) {
111
			obj = menu.getParentItem().getData(AbstractPartRenderer.OWNING_ME);
112
		}
113
		if (obj instanceof MPopupMenu) {
114
			handleContextMenu(event, menu, (MPopupMenu) obj);
115
		} else if (obj instanceof MMenu) {
116
			handleMenu(event, menu, (MMenu) obj);
117
		}
118
	}
119
120
	private void handleMenu(final Event event, final Menu menu,
121
			final MMenu menuModel) {
122
		if ((menu.getStyle() & SWT.BAR) != 0) {
123
			// don't process the menu bar, it's not fair :-)
124
			return;
125
		}
126
		switch (event.type) {
127
		case SWT.Show:
128
			cleanUp(menu);
129
			showMenu(event, menu, menuModel);
130
			break;
131
		case SWT.Hide:
132
			// TODO we'll clean up on show
133
			break;
134
		}
135
	}
136
137
	public void showMenu(final Event event, final Menu menu,
138
			final MMenu menuModel) {
139
		// System.err.println("showMenu: " + menuModel + "\n\t" + menu);
140
	}
141
142
	private void handleContextMenu(final Event event, final Menu menu,
143
			final MPopupMenu menuModel) {
144
		switch (event.type) {
145
		case SWT.Show:
146
			cleanUp(menu);
147
			showPopup(event, menu, menuModel);
148
			break;
149
		case SWT.Hide:
150
			hidePopup(event, menu, menuModel);
151
			break;
152
		}
153
	}
154
155
	public void hidePopup(Event event, Menu menu, MPopupMenu menuModel) {
156
		// System.err.println("hidePopup: " + menuModel + "\n\t" + menu);
157
		final IEclipseContext popupContext = menuModel.getContext();
158
		final IEclipseContext originalChild = (IEclipseContext) popupContext
159
				.get(TMP_ORIGINAL_CONTEXT);
160
		popupContext.remove(TMP_ORIGINAL_CONTEXT);
161
		if (!menu.isDisposed()) {
162
			menu.getDisplay().asyncExec(new Runnable() {
163
				public void run() {
164
					if (originalChild == null) {
165
						popupContext.deactivate();
166
					} else {
167
						originalChild.activate();
168
					}
169
				}
170
			});
171
		}
172
	}
173
174
	public void showPopup(final Event event, final Menu menu,
175
			final MPopupMenu menuModel) {
176
		// System.err.println("showPopup: " + menuModel + "\n\t" + menu);
177
		// we need some context foolery here
178
		final IEclipseContext popupContext = menuModel.getContext();
179
		final IEclipseContext parentContext = popupContext.getParent();
180
		final IEclipseContext originalChild = parentContext.getActiveChild();
181
		popupContext.activate();
182
		popupContext.set(TMP_ORIGINAL_CONTEXT, originalChild);
183
184
	}
185
186
	public void cleanUp(final Menu menu) {
187
		// System.err.println("cleanUp: " + menu);
188
	}
189
190
	public void dispose() {
191
		// System.err.println("dispose");
192
	}
193
}
(-)src/org/eclipse/e4/ui/workbench/swt/modeling/MenuService.java (-20 / +42 lines)
Lines 13-25 Link Here
13
import javax.inject.Inject;
13
import javax.inject.Inject;
14
import org.eclipse.e4.core.contexts.IEclipseContext;
14
import org.eclipse.e4.core.contexts.IEclipseContext;
15
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
15
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
16
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
17
import org.eclipse.e4.ui.model.application.ui.MUIElement;
16
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
18
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
17
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
19
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
18
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
20
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
19
import org.eclipse.swt.SWT;
21
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
20
import org.eclipse.swt.widgets.Control;
22
import org.eclipse.swt.widgets.Control;
21
import org.eclipse.swt.widgets.Event;
22
import org.eclipse.swt.widgets.Listener;
23
import org.eclipse.swt.widgets.Menu;
23
import org.eclipse.swt.widgets.Menu;
24
24
25
public class MenuService implements EMenuService {
25
public class MenuService implements EMenuService {
Lines 34-40 Link Here
34
		for (MMenu mmenu : myPart.getMenus()) {
34
		for (MMenu mmenu : myPart.getMenus()) {
35
			if (menuId.equals(mmenu.getElementId())
35
			if (menuId.equals(mmenu.getElementId())
36
					&& mmenu instanceof MPopupMenu) {
36
					&& mmenu instanceof MPopupMenu) {
37
				if (registerMenu(parentControl, (MPopupMenu) mmenu)) {
37
				Menu menu = registerMenu(parentControl, (MPopupMenu) mmenu,
38
						myPart);
39
				if (menu != null) {
40
					parentControl.setMenu(menu);
38
					return (MPopupMenu) mmenu;
41
					return (MPopupMenu) mmenu;
39
				} else {
42
				} else {
40
					return null;
43
					return null;
Lines 44-68 Link Here
44
		return null;
47
		return null;
45
	}
48
	}
46
49
47
	private boolean registerMenu(final Control parentControl,
50
	public static Menu registerMenu(final Control parentControl,
48
			final MPopupMenu mmenu) {
51
			final MPopupMenu mmenu, final MPart part) {
49
		if (mmenu.getWidget() != null) {
52
		if (mmenu.getWidget() != null) {
50
			return false;
53
			return (Menu) mmenu.getWidget();
51
		}
54
		}
52
		Menu menu = new Menu(parentControl);
55
		// we need to delegate to the renderer so that it "processes" the
53
		parentControl.setMenu(menu);
56
		// MenuManager correctly
54
		mmenu.setWidget(menu);
57
		IRendererFactory rendererFactory = part.getContext().get(
55
		menu.setData(AbstractPartRenderer.OWNING_ME, mmenu);
58
				IRendererFactory.class);
56
		IEclipseContext popupContext = myPart.getContext().createChild(
59
		AbstractPartRenderer renderer = rendererFactory.getRenderer(mmenu,
60
				parentControl);
61
		IEclipseContext popupContext = part.getContext().createChild(
57
				"popup:" + mmenu.getElementId());
62
				"popup:" + mmenu.getElementId());
58
		mmenu.setContext(popupContext);
63
		mmenu.setContext(popupContext);
59
		menu.addListener(SWT.Dispose, new Listener() {
64
		Object widget = renderer.createWidget(mmenu, parentControl);
60
			public void handleEvent(Event event) {
65
		if (!(widget instanceof Menu)) {
61
				mmenu.getContext().dispose();
66
			return null;
62
				mmenu.setContext(null);
67
		}
63
				mmenu.setWidget(null);
68
		renderer.bindWidget(mmenu, widget);
64
			}
69
		renderer.hookControllerLogic(mmenu);
65
		});
70
66
		return true;
71
		// Process its internal structure through the renderer that created
72
		// it
73
		Object castObject = mmenu;
74
		renderer.processContents((MElementContainer<MUIElement>) castObject);
75
76
		// Allow a final chance to set up
77
		renderer.postProcess(mmenu);
78
79
		// Now that we have a widget let the parent (if any) know
80
		if (mmenu.getParent() instanceof MUIElement) {
81
			MElementContainer<MUIElement> parentElement = mmenu.getParent();
82
			AbstractPartRenderer parentRenderer = rendererFactory.getRenderer(
83
					parentElement, null);
84
			if (parentRenderer != null)
85
				parentRenderer.childRendered(parentElement, mmenu);
86
		}
87
88
		return (Menu) widget;
67
	}
89
	}
68
}
90
}
(-)src/org/eclipse/e4/ui/workbench/swt/modeling/MenuServiceFilter.java (-369 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 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.e4.ui.workbench.swt.modeling;
12
13
import java.lang.reflect.InvocationTargetException;
14
import java.lang.reflect.Method;
15
import java.util.ArrayList;
16
import java.util.HashMap;
17
import java.util.List;
18
import javax.inject.Inject;
19
import org.eclipse.core.commands.ParameterizedCommand;
20
import org.eclipse.core.runtime.ISafeRunnable;
21
import org.eclipse.core.runtime.SafeRunner;
22
import org.eclipse.e4.core.commands.EHandlerService;
23
import org.eclipse.e4.core.contexts.IEclipseContext;
24
import org.eclipse.e4.core.services.log.Logger;
25
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
26
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
27
import org.eclipse.e4.ui.internal.workbench.swt.Policy;
28
import org.eclipse.e4.ui.internal.workbench.swt.WorkbenchSWTActivator;
29
import org.eclipse.e4.ui.model.application.MApplication;
30
import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
31
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
32
import org.eclipse.e4.ui.model.application.ui.menu.MMenuContribution;
33
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
34
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
35
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedMenu;
36
import org.eclipse.e4.ui.workbench.IPresentationEngine;
37
import org.eclipse.e4.ui.workbench.modeling.EModelService;
38
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
39
import org.eclipse.jface.action.MenuManager;
40
import org.eclipse.swt.SWT;
41
import org.eclipse.swt.widgets.Event;
42
import org.eclipse.swt.widgets.Listener;
43
import org.eclipse.swt.widgets.Menu;
44
import org.eclipse.swt.widgets.MenuItem;
45
import org.eclipse.swt.widgets.Widget;
46
47
public class MenuServiceFilter implements Listener {
48
	public static final String NUL_MENU_ITEM = "(None Applicable)"; //$NON-NLS-1$
49
50
	private static final String TMP_ORIGINAL_CONTEXT = "MenuServiceFilter.original.context";
51
52
	private static void trace(String msg, Widget menu, MMenu menuModel) {
53
		WorkbenchSWTActivator.trace(Policy.MENUS, msg + ": " + menu + ": "
54
				+ menuModel, null);
55
	}
56
57
	private static Method aboutToShow;
58
59
	public static Method getAboutToShow() {
60
		if (aboutToShow == null) {
61
			try {
62
				aboutToShow = MenuManager.class
63
						.getDeclaredMethod("handleAboutToShow");
64
				aboutToShow.setAccessible(true);
65
			} catch (SecurityException e) {
66
				// TODO Auto-generated catch block
67
				e.printStackTrace();
68
			} catch (NoSuchMethodException e) {
69
				// TODO Auto-generated catch block
70
				e.printStackTrace();
71
			}
72
		}
73
		return aboutToShow;
74
	}
75
76
	@Inject
77
	private MApplication application;
78
79
	@Inject
80
	private IPresentationEngine renderer;
81
82
	@Inject
83
	private Logger logger;
84
85
	@Inject
86
	EModelService modelService;
87
88
	private HashMap<Menu, Runnable> pendingCleanup = new HashMap<Menu, Runnable>();
89
90
	public void handleEvent(final Event event) {
91
		// wrap the handling in a SafeRunner so that exceptions do not prevent
92
		// the menu from being shown
93
		SafeRunner.run(new ISafeRunnable() {
94
			public void handleException(Throwable e) {
95
				if (e instanceof Error) {
96
					// errors are deadly, we shouldn't ignore these
97
					throw (Error) e;
98
				} else {
99
					// log exceptions otherwise
100
					if (logger != null) {
101
						logger.error(e);
102
					}
103
				}
104
			}
105
106
			public void run() throws Exception {
107
				safeHandleEvent(event);
108
			}
109
		});
110
	}
111
112
	private void safeHandleEvent(Event event) {
113
		if (!(event.widget instanceof Menu)) {
114
			return;
115
		}
116
		final Menu menu = (Menu) event.widget;
117
		if (event.type == SWT.Dispose) {
118
			trace("handleMenu.Dispose", menu, null);
119
			cleanUp(menu);
120
		}
121
		Object obj = menu.getData(AbstractPartRenderer.OWNING_ME);
122
		if (obj == null && menu.getParentItem() != null) {
123
			obj = menu.getParentItem().getData(AbstractPartRenderer.OWNING_ME);
124
		}
125
		if (obj instanceof MRenderedMenu) {
126
			handlerRenderedMenu(event, menu, (MRenderedMenu) obj);
127
		} else if (obj instanceof MPopupMenu) {
128
			handleContextMenu(event, menu, (MPopupMenu) obj);
129
		} else if (obj instanceof MMenu) {
130
			handleMenu(event, menu, (MMenu) obj);
131
		}
132
	}
133
134
	private void handleMenu(final Event event, final Menu menu,
135
			final MMenu menuModel) {
136
		if ((menu.getStyle() & SWT.BAR) != 0) {
137
			// don't process the menu bar, it's not fair :-)
138
			return;
139
		}
140
		switch (event.type) {
141
		case SWT.Show:
142
			trace("handleMenu.Show", menu, menuModel);
143
			cleanUp(menu);
144
			showMenu(event, menu, menuModel);
145
			break;
146
		case SWT.Hide:
147
			trace("handleMenu.Hide", menu, menuModel);
148
			// TODO we'll clean up on show
149
			break;
150
		}
151
	}
152
153
	public void showMenu(final Event event, final Menu menu,
154
			final MMenu menuModel) {
155
		final IEclipseContext parentContext = modelService
156
				.getContainingContext(menuModel);
157
158
		final ArrayList<MMenuContribution> toContribute = new ArrayList<MMenuContribution>();
159
		final ArrayList<MMenuElement> menuContributionsToRemove = new ArrayList<MMenuElement>();
160
		ExpressionContext eContext = new ExpressionContext(parentContext);
161
		ContributionsAnalyzer.gatherMenuContributions(menuModel,
162
				application.getMenuContributions(), menuModel.getElementId(),
163
				toContribute, eContext, false);
164
		if (menu.getItemCount() == 1) {
165
			MenuItem item = menu.getItem(0);
166
			if (NUL_MENU_ITEM.equals(item.getText())) {
167
				item.dispose();
168
			}
169
		}
170
		ContributionsAnalyzer.addMenuContributions(menuModel, toContribute,
171
				menuContributionsToRemove);
172
173
		// create a cleanup routine for the Hide or next Show
174
		pendingCleanup.put(menu, new Runnable() {
175
			public void run() {
176
				if (!menu.isDisposed()) {
177
					unrender(menuContributionsToRemove);
178
				}
179
				removeMenuContributions(menuModel, menuContributionsToRemove);
180
			}
181
		});
182
		render(menu, menuModel);
183
		if (menu.getItemCount() == 0) {
184
			MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
185
			menuItem.setText(NUL_MENU_ITEM);
186
			menuItem.setEnabled(false);
187
		}
188
	}
189
190
	private void handleContextMenu(final Event event, final Menu menu,
191
			final MPopupMenu menuModel) {
192
		switch (event.type) {
193
		case SWT.Show:
194
			trace("handleContextMenu.Show", menu, menuModel);
195
			cleanUp(menu);
196
			showPopup(event, menu, menuModel);
197
			break;
198
		case SWT.Hide:
199
			trace("handleContextMenu.Hide", menu, menuModel);
200
			hidePopup(event, menu, menuModel);
201
			break;
202
		}
203
	}
204
205
	public void hidePopup(Event event, Menu menu, MPopupMenu menuModel) {
206
		final IEclipseContext popupContext = menuModel.getContext();
207
		final IEclipseContext originalChild = (IEclipseContext) popupContext
208
				.get(TMP_ORIGINAL_CONTEXT);
209
		popupContext.remove(TMP_ORIGINAL_CONTEXT);
210
		if (!menu.isDisposed()) {
211
			menu.getDisplay().asyncExec(new Runnable() {
212
				public void run() {
213
					if (originalChild == null) {
214
						popupContext.deactivate();
215
					} else {
216
						originalChild.activate();
217
					}
218
				}
219
			});
220
		}
221
	}
222
223
	public void showPopup(final Event event, final Menu menu,
224
			final MPopupMenu menuModel) {
225
		// System.err.println("showPopup: " + menuModel + "\n\t" + menu);
226
		// we need some context foolery here
227
		final IEclipseContext popupContext = menuModel.getContext();
228
		final IEclipseContext parentContext = popupContext.getParent();
229
		final IEclipseContext originalChild = parentContext.getActiveChild();
230
		popupContext.activate();
231
		popupContext.set(TMP_ORIGINAL_CONTEXT, originalChild);
232
233
		final ArrayList<MMenuContribution> toContribute = new ArrayList<MMenuContribution>();
234
		final ArrayList<MMenuElement> menuContributionsToRemove = new ArrayList<MMenuElement>();
235
		ExpressionContext eContext = new ExpressionContext(popupContext);
236
		ContributionsAnalyzer.gatherMenuContributions(menuModel,
237
				application.getMenuContributions(), menuModel.getElementId(),
238
				toContribute, eContext, true);
239
240
		for (String tag : menuModel.getTags()) {
241
			if (tag.startsWith("popup:") && tag.length() > 6) {
242
				ContributionsAnalyzer.gatherMenuContributions(menuModel,
243
						application.getMenuContributions(), tag.substring(6),
244
						toContribute, eContext, false);
245
			}
246
		}
247
		ContributionsAnalyzer.addMenuContributions(menuModel, toContribute,
248
				menuContributionsToRemove);
249
250
		// create a cleanup routine for the Hide or next Show
251
		pendingCleanup.put(menu, new Runnable() {
252
			public void run() {
253
				if (!menu.isDisposed()) {
254
					unrender(menuContributionsToRemove);
255
				}
256
				removeMenuContributions(menuModel, menuContributionsToRemove);
257
			}
258
		});
259
		render(menu, menuModel);
260
	}
261
262
	private void render(final Menu menu, final MMenu menuModel) {
263
		trace("render", menu, menuModel);
264
		for (MMenuElement element : menuModel.getChildren()) {
265
			renderer.createGui(element, menu, null);
266
			if (element instanceof MHandledMenuItem) {
267
				setEnabled((MHandledMenuItem) element);
268
			}
269
		}
270
	}
271
272
	private void setEnabled(MHandledMenuItem item) {
273
		if (!item.isToBeRendered() || !item.isVisible()
274
				|| item.getWidget() == null) {
275
			return;
276
		}
277
		ParameterizedCommand cmd = item.getWbCommand();
278
		if (cmd == null) {
279
			return;
280
		}
281
		final IEclipseContext lclContext = modelService
282
				.getContainingContext(item);
283
		EHandlerService service = lclContext.get(EHandlerService.class);
284
		item.setEnabled(service.canExecute(cmd));
285
	}
286
287
	private void unrender(final List<MMenuElement> menuModel) {
288
		trace("unrender", null, null);
289
		for (MMenuElement element : menuModel) {
290
			renderer.removeGui(element);
291
		}
292
	}
293
294
	private void removeMenuContributions(final MMenu menuModel,
295
			final ArrayList<MMenuElement> menuContributionsToRemove) {
296
		for (MMenuElement item : menuContributionsToRemove) {
297
			trace("removeMenuContributions " + item,
298
					(Widget) menuModel.getWidget(), menuModel);
299
			menuModel.getChildren().remove(item);
300
		}
301
	}
302
303
	private void handlerRenderedMenu(final Event event, final Menu menu,
304
			final MRenderedMenu menuModel) {
305
		// Do nothing here for the moment, except process any cleanups
306
		switch (event.type) {
307
		case SWT.Show:
308
			trace("handlerRenderedMenu.Show", menu, menuModel);
309
			cleanUp(menu);
310
			showRenderedMenu(event, menu, menuModel);
311
			break;
312
		case SWT.Hide:
313
			trace("handlerRenderedMenu.Hide", menu, menuModel);
314
			// TODO don't care
315
			break;
316
		}
317
	}
318
319
	public void showRenderedMenu(final Event event, final Menu menu,
320
			final MRenderedMenu menuModel) {
321
		if (!(menuModel.getContributionManager() instanceof MenuManager)) {
322
			return;
323
		}
324
325
		MenuManager manager = (MenuManager) menuModel.getContributionManager();
326
		Method handleAboutToShow = getAboutToShow();
327
		try {
328
			handleAboutToShow.invoke(manager);
329
		} catch (IllegalArgumentException e) {
330
			// TODO Auto-generated catch block
331
			e.printStackTrace();
332
		} catch (IllegalAccessException e) {
333
			// TODO Auto-generated catch block
334
			e.printStackTrace();
335
		} catch (InvocationTargetException e) {
336
			// TODO Auto-generated catch block
337
			e.printStackTrace();
338
		}
339
340
		if (menuModel.getChildren().size() == 1
341
				&& menuModel.getChildren().get(0) instanceof MPopupMenu) {
342
			showPopup(event, menu, (MPopupMenu) menuModel.getChildren().get(0));
343
		} else {
344
			showMenu(event, menu, menuModel);
345
		}
346
		event.type = SWT.None;
347
		event.doit = false;
348
	}
349
350
	public void cleanUp(final Menu menu) {
351
		trace("cleanUp", menu, null);
352
		if (pendingCleanup.isEmpty()) {
353
			return;
354
		}
355
		Runnable cleanUp = pendingCleanup.remove(menu);
356
		if (cleanUp != null) {
357
			trace("cleanUp.run()", menu, null);
358
			cleanUp.run();
359
		}
360
	}
361
362
	public void dispose() {
363
		Menu[] keys = pendingCleanup.keySet().toArray(
364
				new Menu[pendingCleanup.size()]);
365
		for (Menu menu : keys) {
366
			cleanUp(menu);
367
		}
368
	}
369
}
(-)Eclipse UI/org/eclipse/ui/internal/PopupMenuExtender.java (-100 / +34 lines)
Lines 24-43 Link Here
24
import org.eclipse.core.runtime.IRegistryChangeEvent;
24
import org.eclipse.core.runtime.IRegistryChangeEvent;
25
import org.eclipse.core.runtime.IRegistryChangeListener;
25
import org.eclipse.core.runtime.IRegistryChangeListener;
26
import org.eclipse.core.runtime.Platform;
26
import org.eclipse.core.runtime.Platform;
27
import org.eclipse.e4.core.contexts.IEclipseContext;
28
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
27
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
29
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
28
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
30
import org.eclipse.e4.ui.model.application.MApplication;
29
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
30
import org.eclipse.e4.ui.model.application.ui.MUIElement;
31
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
31
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
32
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
32
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
33
import org.eclipse.e4.ui.model.application.ui.menu.MMenuContribution;
34
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
35
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
33
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
36
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedMenu;
37
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
34
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
38
import org.eclipse.e4.ui.workbench.modeling.ExpressionContext;
35
import org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer;
36
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
37
import org.eclipse.e4.ui.workbench.swt.modeling.MenuService;
39
import org.eclipse.jface.action.ContributionManager;
38
import org.eclipse.jface.action.ContributionManager;
40
import org.eclipse.jface.action.GroupMarker;
41
import org.eclipse.jface.action.IContributionItem;
39
import org.eclipse.jface.action.IContributionItem;
42
import org.eclipse.jface.action.IMenuListener2;
40
import org.eclipse.jface.action.IMenuListener2;
43
import org.eclipse.jface.action.IMenuManager;
41
import org.eclipse.jface.action.IMenuManager;
Lines 51-57 Link Here
51
import org.eclipse.swt.widgets.Display;
49
import org.eclipse.swt.widgets.Display;
52
import org.eclipse.ui.IEditorPart;
50
import org.eclipse.ui.IEditorPart;
53
import org.eclipse.ui.IWorkbench;
51
import org.eclipse.ui.IWorkbench;
54
import org.eclipse.ui.IWorkbenchActionConstants;
55
import org.eclipse.ui.IWorkbenchPart;
52
import org.eclipse.ui.IWorkbenchPart;
56
import org.eclipse.ui.IWorkbenchPartSite;
53
import org.eclipse.ui.IWorkbenchPartSite;
57
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
54
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
Lines 93-100 Link Here
93
	
90
	
94
	private ArrayList actionContributionCache = new ArrayList();
91
	private ArrayList actionContributionCache = new ArrayList();
95
	private ArrayList managerContributionCache = new ArrayList();
92
	private ArrayList managerContributionCache = new ArrayList();
96
	private ArrayList<MRenderedMenu> renderedMenuCache = new ArrayList<MRenderedMenu>();
97
	private ArrayList<MRenderedMenu> lastRenderedMenuCache = new ArrayList<MRenderedMenu>();
98
	private boolean cleanupNeeded = false;
93
	private boolean cleanupNeeded = false;
99
94
100
	private MPart modelPart;
95
	private MPart modelPart;
Lines 159-193 Link Here
159
		}
154
		}
160
		menuModel = null;
155
		menuModel = null;
161
		for (MMenu item : modelPart.getMenus()) {
156
		for (MMenu item : modelPart.getMenus()) {
162
			if (id.equals(item.getElementId()) && item instanceof MRenderedMenu
157
			if (id.equals(item.getElementId()) && item instanceof MPopupMenu
163
					&& item.getTags().contains("popup")) { //$NON-NLS-1$
158
					&& item.getTags().contains("popup")) { //$NON-NLS-1$
164
				menuModel = (MRenderedMenu) item;
159
				menuModel = (MPopupMenu) item;
165
				break;
160
				break;
166
			}
161
			}
167
		}
162
		}
168
		if (menuModel == null) {
163
		if (menuModel == null) {
169
			menuModel = MenuFactoryImpl.eINSTANCE.createRenderedMenu();
164
			menuModel = MenuFactoryImpl.eINSTANCE.createPopupMenu();
170
			menuModel.setElementId(id);
165
			menuModel.setElementId(id);
171
			menuModel.getTags().add(ContributionsAnalyzer.MC_POPUP);
166
			menuModel.getTags().add(ContributionsAnalyzer.MC_POPUP);
172
			modelPart.getMenus().add(menuModel);
167
			modelPart.getMenus().add(menuModel);
173
			MPopupMenu popup = MenuFactoryImpl.eINSTANCE.createPopupMenu();
174
			popup.setElementId(id);
175
			popup.getTags().add(ContributionsAnalyzer.MC_POPUP);
176
			menuModel.getChildren().add(popup);
177
		}
168
		}
178
		menuModel.setContributionManager(menu);
169
		IRendererFactory factory = modelPart.getContext().get(IRendererFactory.class);
170
		AbstractPartRenderer obj = factory.getRenderer(menuModel, null);
171
		if (obj instanceof MenuManagerRenderer) {
172
			((MenuManagerRenderer) obj).linkModelToManager(menuModel, menu);
173
		}
179
		registerE4Support();
174
		registerE4Support();
180
	}
175
	}
181
176
182
	private void registerE4Support() {
177
	private void registerE4Support() {
183
		if (menuModel.getWidget() == null && menu.getMenu() != null) {
178
		if (menuModel.getWidget() == null && menu.getMenu() != null) {
184
			menuModel.setWidget(menu.getMenu());
179
			MenuService.registerMenu(menu.getMenu().getParent(), menuModel, modelPart);
185
			menu.getMenu().setData(AbstractPartRenderer.OWNING_ME, menuModel);
186
			MPopupMenu popup = (MPopupMenu) menuModel.getChildren().get(0);
187
			IEclipseContext popupContext = modelPart.getContext().createChild(
188
					"popup:" + popup.getElementId()); //$NON-NLS-1$
189
			popup.setContext(popupContext);
190
191
		}
180
		}
192
	}
181
	}
193
	// getMenuId() added by Dan Rubel (dan_rubel@instantiations.com)
182
	// getMenuId() added by Dan Rubel (dan_rubel@instantiations.com)
Lines 227-233 Link Here
227
    public final void addMenuId(final String menuId) {
216
    public final void addMenuId(final String menuId) {
228
		bitSet &= ~STATIC_ACTION_READ;
217
		bitSet &= ~STATIC_ACTION_READ;
229
		if (menuModel != null) {
218
		if (menuModel != null) {
230
			List<String> tags = menuModel.getChildren().get(0).getTags();
219
			List<String> tags = menuModel.getTags();
231
			String tag = "popup:" + menuId; //$NON-NLS-1$
220
			String tag = "popup:" + menuId; //$NON-NLS-1$
232
			if (!tags.contains(tag)) {
221
			if (!tags.contains(tag)) {
233
				tags.add(tag);
222
				tags.add(tag);
Lines 388-490 Link Here
388
			}
377
			}
389
		}
378
		}
390
    	
379
    	
380
		addMenuContributions(mgr);
381
391
    	readStaticActions();
382
    	readStaticActions();
392
        // test for additions removed to comply with menu contributions
383
        // test for additions removed to comply with menu contributions
393
        if (menuWrapper != null) {
384
        if (menuWrapper != null) {
394
            mgr = menuWrapper;
385
            mgr = menuWrapper;
395
            menuWrapper.removeAll();
386
            menuWrapper.removeAll();
396
        }
387
        }
397
		addMenuContributions(mgr);
398
        if ((bitSet & INCLUDE_EDITOR_INPUT) != 0) {
388
        if ((bitSet & INCLUDE_EDITOR_INPUT) != 0) {
399
            addEditorActions(mgr);
389
            addEditorActions(mgr);
400
        }
390
        }
401
        addObjectActions(mgr);
391
        addObjectActions(mgr);
402
        addStaticActions(mgr);
392
        addStaticActions(mgr);
403
        cleanUpContributionCache();
404
    }
393
    }
405
    
394
    
406
395
407
	/**
396
	/**
397
	 * well, this goes to the renderer.
398
	 * 
408
	 * @param mgr
399
	 * @param mgr
409
	 */
400
	 */
410
	private void addMenuContributions(IMenuManager mgr) {
401
	private void addMenuContributions(IMenuManager mgr) {
411
		MPopupMenu popup = (MPopupMenu) menuModel.getChildren().get(0);
402
		IRendererFactory factory = modelPart.getContext().get(IRendererFactory.class);
412
		final IEclipseContext popupContext = popup.getContext();
403
		AbstractPartRenderer obj = factory.getRenderer(menuModel, null);
413
		final IEclipseContext parentContext = popupContext.getParent();
404
		if (obj instanceof MenuManagerRenderer) {
414
		// final IEclipseContext originalChild = (IEclipseContext) parentContext
405
			MenuManagerRenderer renderer = (MenuManagerRenderer) obj;
415
		// .getLocal(IContextConstants.ACTIVE_CHILD);
406
			renderer.reconcileManagerToModel(menu, menuModel);
416
		// parentContext.set(IContextConstants.ACTIVE_CHILD, popupContext);
407
			renderer.processContributions(menuModel, false);
417
		// popupContext.set(TMP_ORIGINAL_CONTEXT, originalChild);
408
			// double cast because we're bad people
418
		MApplication application = parentContext.get(MApplication.class);
409
			renderer.processContents((MElementContainer<MUIElement>) ((Object) menuModel));
419
420
		final ArrayList<MMenuContribution> toContribute = new ArrayList<MMenuContribution>();
421
		// final ArrayList<MMenuElement> menuContributionsToRemove = new
422
		// ArrayList<MMenuElement>();
423
		ExpressionContext eContext = new ExpressionContext(popupContext);
424
		ContributionsAnalyzer.gatherMenuContributions(popup, application.getMenuContributions(),
425
				popup.getElementId(), toContribute, eContext, true);
426
427
		for (String tag : popup.getTags()) {
428
			if (tag.startsWith("popup:") && tag.length() > 6) { //$NON-NLS-1$
429
				ContributionsAnalyzer.gatherMenuContributions(popup,
430
						application.getMenuContributions(), tag.substring(6), toContribute,
431
						eContext, false);
432
			}
433
		}
434
		for (MMenuContribution contribution : toContribute) {
435
			String positionInParent = contribution.getPositionInParent();
436
			String id = null;
437
			String modifier = null;
438
			if (positionInParent != null && positionInParent.length() > 0) {
439
				String[] array = positionInParent.split("="); //$NON-NLS-1$
440
				modifier = array[0];
441
				id = array[1];
442
			}
443
			if (id == null) {
444
				continue;
445
			}
446
			IContributionItem item = mgr.find(id);
447
			if (item == null) {
448
				if (IWorkbenchActionConstants.MB_ADDITIONS.equals(id)) {
449
					mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
450
				} else {
451
					continue;
452
				}
453
			}
454
			for (MMenuElement element : contribution.getChildren()) {
455
				if (element instanceof MMenu) {
456
					MMenu menu = (MMenu) element;
457
					if (mgr.find(menu.getElementId()) != null) {
458
						continue;
459
					}
460
					MenuManager submenu = new MenuManager(menu.getLabel(), menu.getElementId());
461
					if (modifier.equals("before")) { //$NON-NLS-1$
462
						mgr.insertBefore(id, submenu);
463
					} else {
464
						mgr.insertAfter(id, submenu);
465
					}
466
					MRenderedMenu renderedMenu = MenuFactoryImpl.eINSTANCE.createRenderedMenu();
467
					renderedMenu.setElementId(menu.getElementId());
468
					renderedMenu.getTags().add(ContributionsAnalyzer.MC_POPUP);
469
					renderedMenu.setContributionManager(submenu);
470
					popup.getChildren().add(renderedMenu);
471
					renderedMenuCache.add(renderedMenu);
472
				}
473
			}
474
		}
410
		}
475
	}
411
	}
476
412
477
	private MRenderedMenu menuModel;
413
	private MPopupMenu menuModel;
478
    
414
    
479
    /**
415
    /**
480
	 * Notifies the listener that the menu is about to be hidden.
416
	 * Notifies the listener that the menu is about to be hidden.
481
	 */
417
	 */
482
    public final void menuAboutToHide(final IMenuManager mgr) {
418
    public final void menuAboutToHide(final IMenuManager mgr) {
483
    	gatherContributions(mgr);
419
    	gatherContributions(mgr);
484
		if (!renderedMenuCache.isEmpty()) {
485
			lastRenderedMenuCache = renderedMenuCache;
486
			renderedMenuCache = new ArrayList<MRenderedMenu>();
487
		}
488
		cleanupNeeded = true;
420
		cleanupNeeded = true;
489
    	// Remove this menu as a visible menu.
421
    	// Remove this menu as a visible menu.
490
    	final IWorkbenchPartSite site = part.getSite();
422
    	final IWorkbenchPartSite site = part.getSite();
Lines 539-549 Link Here
539
			}
471
			}
540
		}
472
		}
541
473
542
		for (MRenderedMenu rmenu : lastRenderedMenuCache) {
474
		IRendererFactory factory = modelPart.getContext().get(IRendererFactory.class);
543
			MPopupMenu popup = (MPopupMenu) menuModel.getChildren().get(0);
475
		AbstractPartRenderer obj = factory.getRenderer(menuModel, null);
544
			popup.getChildren().remove(rmenu);
476
		if (obj instanceof MenuManagerRenderer) {
477
			MenuManagerRenderer renderer = (MenuManagerRenderer) obj;
478
			renderer.cleanUp(menuModel);
545
		}
479
		}
546
		lastRenderedMenuCache.clear();
480
547
		managerContributionCache.clear();
481
		managerContributionCache.clear();
548
482
549
	}
483
	}
(-)Eclipse UI/org/eclipse/ui/internal/e4/compatibility/CompatibilityView.java (-6 / +15 lines)
Lines 12-25 Link Here
12
package org.eclipse.ui.internal.e4.compatibility;
12
package org.eclipse.ui.internal.e4.compatibility;
13
13
14
import javax.inject.Inject;
14
import javax.inject.Inject;
15
import org.eclipse.e4.core.contexts.IEclipseContext;
15
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
16
import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer;
17
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
16
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
18
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
17
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
19
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
18
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedMenu;
19
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedToolBar;
20
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedToolBar;
20
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
21
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
21
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
22
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
23
import org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer;
22
import org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer;
24
import org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer;
25
import org.eclipse.e4.ui.workbench.swt.factories.IRendererFactory;
23
import org.eclipse.jface.action.MenuManager;
26
import org.eclipse.jface.action.MenuManager;
24
import org.eclipse.jface.action.ToolBarManager;
27
import org.eclipse.jface.action.ToolBarManager;
25
import org.eclipse.swt.widgets.Composite;
28
import org.eclipse.swt.widgets.Composite;
Lines 75-90 Link Here
75
		// dispose the tb, it will be re-created when the tab is shown
78
		// dispose the tb, it will be re-created when the tab is shown
76
		tb.dispose();
79
		tb.dispose();
77
80
81
		IEclipseContext context = getModel().getContext();
82
		IRendererFactory rendererFactory = context.get(IRendererFactory.class);
83
78
		MenuManager mm = (MenuManager) actionBars.getMenuManager();
84
		MenuManager mm = (MenuManager) actionBars.getMenuManager();
79
		MRenderedMenu menu = null;
85
		MMenu menu = null;
80
		for (MMenu me : part.getMenus()) {
86
		for (MMenu me : part.getMenus()) {
81
			if (me.getTags().contains(StackRenderer.TAG_VIEW_MENU) && (me instanceof MRenderedMenu)) {
87
			if (me.getTags().contains(StackRenderer.TAG_VIEW_MENU)) {
82
				menu = (MRenderedMenu) me;
88
				menu = me;
83
				break;
89
				break;
84
			}
90
			}
85
		}
91
		}
86
		if (menu == null) {
92
		if (menu == null) {
87
			menu = MenuFactoryImpl.eINSTANCE.createRenderedMenu();
93
			menu = MenuFactoryImpl.eINSTANCE.createMenu();
88
			menu.setElementId(part.getElementId());
94
			menu.setElementId(part.getElementId());
89
95
90
			menu.getTags().add(StackRenderer.TAG_VIEW_MENU);
96
			menu.getTags().add(StackRenderer.TAG_VIEW_MENU);
Lines 92-98 Link Here
92
			part.getMenus().add(menu);
98
			part.getMenus().add(menu);
93
99
94
		}
100
		}
95
		menu.setContributionManager(mm);
101
		AbstractPartRenderer apr = rendererFactory.getRenderer(menu, parent);
102
		if (apr instanceof MenuManagerRenderer) {
103
			((MenuManagerRenderer) apr).linkModelToManager(menu, mm);
104
		}
96
105
97
		// Construct the toolbar (if necessary)
106
		// Construct the toolbar (if necessary)
98
		MToolBar toolbar = part.getToolbar();
107
		MToolBar toolbar = part.getToolbar();

Return to bug 325392