Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemy Suen2012-02-13 18:03:03 +0000
committerRemy Suen2012-02-13 18:03:03 +0000
commit5185d9e93948557023700a3cfd8d3ff2480223ee (patch)
treed76f5b82404fdecf333bc85aba93c9e3cc8358c2
parentf2a8ce2a9c2725653391ee3326262a984a9fa896 (diff)
downloadeclipse.platform.ui-5185d9e93948557023700a3cfd8d3ff2480223ee.tar.gz
eclipse.platform.ui-5185d9e93948557023700a3cfd8d3ff2480223ee.tar.xz
eclipse.platform.ui-5185d9e93948557023700a3cfd8d3ff2480223ee.zip
Bug 319621 [Compatibility] All views now have view menusv20120213-1803
A part's menu is a dynamic item in that when the part is first constructed, it may not have a menu but a menu may become necessary at a later point in time when other variables become satisfied. Likewise, a part may start of needing a menu but this requirement may be lifted later. To properly react to this, a RunAndTrack is needed to determine when a part's menu should be rendered or not.
-rw-r--r--bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributionRecord.java5
-rw-r--r--bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java12
-rw-r--r--bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java201
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ActionBars.java26
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/CompatibilityView.java36
5 files changed, 259 insertions, 21 deletions
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributionRecord.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributionRecord.java
index 2d7c7e60ec3..c9ccfde24c0 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributionRecord.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ContributionRecord.java
@@ -110,7 +110,10 @@ public class ContributionRecord {
}
if (changed) {
- getManagerForModel().markDirty();
+ MenuManager manager = getManagerForModel();
+ if (manager != null) {
+ manager.markDirty();
+ }
}
}
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java
index a5ab9bf26b2..ac990eff679 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation and others.
+ * Copyright (c) 2009, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -31,6 +31,7 @@ import org.eclipse.e4.ui.model.application.ui.MCoreExpression;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.MUILabel;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
@@ -437,7 +438,7 @@ public class MenuManagerRenderer extends SWTPartRenderer {
if (!record.mergeIntoModel()) {
return false;
}
- if (menuBar) {
+ if (menuBar || isPartMenu(menuModel)) {
final IEclipseContext parentContext = modelService
.getContainingContext(menuModel);
parentContext.runAndTrack(new RunAndTrack() {
@@ -452,6 +453,13 @@ public class MenuManagerRenderer extends SWTPartRenderer {
return true;
}
+ private boolean isPartMenu(MMenu menuModel) {
+ // don't want popup menus as their visibility does not need to be
+ // tracked by a separate RunAndTrack
+ return !(menuModel instanceof MPopupMenu)
+ && ((EObject) menuModel).eContainer() instanceof MPart;
+ }
+
public ArrayList<ContributionRecord> getList(MMenuElement item) {
ArrayList<ContributionRecord> tmp = sharedElementToRecord.get(item);
if (tmp == null) {
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
index d429220a61f..c36b4d27b8d 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
@@ -32,6 +32,9 @@ import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MStackElement;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
+import org.eclipse.e4.ui.model.application.ui.menu.MOpaqueMenuItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MOpaqueMenuSeparator;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
import org.eclipse.e4.ui.services.IStylingEngine;
import org.eclipse.e4.ui.widgets.CTabFolder;
@@ -45,6 +48,7 @@ import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.swt.util.ISWTResourceUtilities;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
@@ -114,6 +118,13 @@ public class StackRenderer extends LazyStackRenderer {
private EventHandler dirtyUpdater;
+ /**
+ * An event handler for listening to changes to the state of view menus and
+ * its child menu items. Depending on what state these items are in, the
+ * view menu should or should not be rendered in the tab folder.
+ */
+ private EventHandler viewMenuUpdater;
+
private boolean ignoreTabSelChanges = false;
private ActivationJob activationJob = null;
@@ -329,6 +340,92 @@ public class StackRenderer extends LazyStackRenderer {
eventBroker.subscribe(UIEvents.buildTopic(UIEvents.Dirtyable.TOPIC,
UIEvents.Dirtyable.DIRTY), dirtyUpdater);
+
+ viewMenuUpdater = new EventHandler() {
+ public void handleEvent(Event event) {
+ Object objElement = event
+ .getProperty(UIEvents.EventTags.ELEMENT);
+
+ // Ensure that this event is for a MMenuItem
+ if (!(objElement instanceof MMenuElement)) {
+ return;
+ }
+
+ EObject parent = ((EObject) objElement).eContainer();
+ while (parent instanceof MMenuElement) {
+ MUIElement element = (MUIElement) parent;
+ if (!element.isToBeRendered() || !element.isVisible()) {
+ return;
+ }
+
+ objElement = parent;
+ parent = parent.eContainer();
+ }
+
+ // if we're a view menu, the parent element is a part
+ if (!(parent instanceof MPart)) {
+ return;
+ }
+
+ MPart element = (MPart) parent;
+ MUIElement parentElement = element.getParent();
+ if (parentElement == null) {
+ MPlaceholder placeholder = element.getCurSharedRef();
+ if (placeholder == null) {
+ return;
+ }
+
+ parentElement = placeholder.getParent();
+ if (parentElement == null) {
+ return;
+ }
+ }
+
+ Object widget = parentElement.getWidget();
+ if (widget instanceof CTabFolder) {
+ Boolean newValue = (Boolean) event
+ .getProperty(UIEvents.EventTags.NEW_VALUE);
+ CTabFolder folder = (CTabFolder) widget;
+ if (newValue.booleanValue()) {
+ if (getViewMenuTB(folder) == null) {
+ disposeViewMenu(folder);
+ setupMenuButton(element, folder);
+ layoutTopRight(folder);
+ }
+ } else if (!isMenuVisible((MMenu) objElement)) {
+ disposeViewMenu(folder);
+ }
+ }
+ }
+ };
+ eventBroker
+ .subscribe(UIEvents.UIElement.TOPIC_VISIBLE, viewMenuUpdater);
+ eventBroker.subscribe(UIEvents.UIElement.TOPIC_TOBERENDERED,
+ viewMenuUpdater);
+ }
+
+ /**
+ * Determines if the menu provided or any one of its children should be
+ * rendered.
+ *
+ * @param menu
+ * the menu to determine if it should be displayed in the tab
+ * folder
+ * @return <tt>true</tt> if the menu should be drawn in the tab folder,
+ * <tt>false</tt> otherwise
+ */
+ private boolean isMenuVisible(MMenu menu) {
+ if (menu.isToBeRendered() && menu.isVisible()) {
+ for (MMenuElement element : menu.getChildren()) {
+ if (element.isToBeRendered() && element.isVisible()) {
+ return true;
+ } else if (element instanceof MMenu
+ && isMenuVisible((MMenu) element)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
protected void updateTab(CTabItem cti, MPart part, String attName,
@@ -361,6 +458,7 @@ public class StackRenderer extends LazyStackRenderer {
eventBroker.unsubscribe(itemUpdater);
eventBroker.unsubscribe(dirtyUpdater);
+ eventBroker.unsubscribe(viewMenuUpdater);
}
private String getLabel(MUILabel itemPart, String newName) {
@@ -497,7 +595,20 @@ public class StackRenderer extends LazyStackRenderer {
return (Composite) ctf.getData(TOP_RIGHT);
}
+ /**
+ * Disposes of the view menu associated with the given tab folder.
+ *
+ * @param ctf
+ * the tab folder to clear of its view menu
+ */
+ public void disposeViewMenu(CTabFolder ctf) {
+ ToolBar vmTB = getViewMenuTB(ctf);
+ if (vmTB != null && !vmTB.isDisposed())
+ vmTB.dispose();
+ }
+
public void clearTR(CTabFolder ctf) {
+ disposeViewMenu(ctf);
ToolBar vmTB = getViewMenuTB(ctf);
if (vmTB != null && !vmTB.isDisposed())
vmTB.dispose();
@@ -525,7 +636,16 @@ public class StackRenderer extends LazyStackRenderer {
}
setupMenuButton(part, ctf);
+ layoutTopRight(ctf);
+ }
+ /**
+ * Asks the specified tab folder to layout its top right control.
+ *
+ * @param ctf
+ * the tab folder that should be laid out
+ */
+ public void layoutTopRight(CTabFolder ctf) {
Composite trComp = getTRComposite(ctf);
if (trComp.getChildren().length > 0) {
trComp.setVisible(true);
@@ -535,8 +655,8 @@ public class StackRenderer extends LazyStackRenderer {
trComp.setVisible(false);
}
- trComp.layout();
- ctf.layout();
+ trComp.pack();
+ ctf.layout(true, true);
}
private MToolBar getViewTB(CTabFolder ctf) {
@@ -874,11 +994,19 @@ public class StackRenderer extends LazyStackRenderer {
adjustTR(ctf, part);
}
- private void setupMenuButton(MPart part, CTabFolder ctf) {
+ /**
+ * Creates a view menu for the given part in the contained tab folder.
+ *
+ * @param part
+ * the part that should have its view menu created
+ * @param ctf
+ * the containing tab folder
+ */
+ public void setupMenuButton(MPart part, CTabFolder ctf) {
MMenu viewMenu = getViewMenu(part);
// View menu (if any)
- if (viewMenu != null) {
+ if (viewMenu != null && hasVisibleMenuItems(viewMenu, part)) {
showMenuButton(part, ctf, viewMenu);
} else {
// hide the menu's TB
@@ -1170,10 +1298,73 @@ public class StackRenderer extends LazyStackRenderer {
return null;
}
for (MMenu menu : part.getMenus()) {
- if (menu.getTags().contains(TAG_VIEW_MENU) && menu.isToBeRendered()) {
+ if (menu.getTags().contains(TAG_VIEW_MENU)) {
return menu;
}
}
return null;
}
+
+ /**
+ * Determine whether the given view menu has any visible menu items.
+ *
+ * @param viewMenu
+ * the view menu to check
+ * @param part
+ * the view menu's parent part
+ * @return <tt>true</tt> if the specified view menu has visible children,
+ * <tt>false</tt> otherwise
+ */
+ private boolean hasVisibleMenuItems(MMenu viewMenu, MPart part) {
+ if (!viewMenu.isToBeRendered() || !viewMenu.isVisible()) {
+ return false;
+ }
+
+ for (MMenuElement menuElement : viewMenu.getChildren()) {
+ if (menuElement.isToBeRendered() && menuElement.isVisible()) {
+ if (menuElement instanceof MOpaqueMenuItem) {
+ IContributionItem item = (IContributionItem) ((MOpaqueMenuItem) menuElement)
+ .getOpaqueItem();
+ if (item != null && item.isVisible()) {
+ return true;
+ }
+ } else if (menuElement instanceof MOpaqueMenuSeparator) {
+ IContributionItem item = (IContributionItem) ((MOpaqueMenuSeparator) menuElement)
+ .getOpaqueItem();
+ if (item != null && item.isVisible()) {
+ return true;
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+
+ Object menuRenderer = viewMenu.getRenderer();
+ if (menuRenderer instanceof MenuManagerRenderer) {
+ MenuManager manager = ((MenuManagerRenderer) menuRenderer)
+ .getManager(viewMenu);
+ if (manager != null && manager.isVisible()) {
+ return true;
+ }
+ }
+
+ Control control = (Control) part.getWidget();
+ Menu menu = (Menu) renderer.createGui(viewMenu, control.getShell(),
+ part.getContext());
+ if (menu != null) {
+ menuRenderer = viewMenu.getRenderer();
+ if (menuRenderer instanceof MenuManagerRenderer) {
+ MenuManagerRenderer menuManagerRenderer = (MenuManagerRenderer) menuRenderer;
+ MenuManager manager = menuManagerRenderer.getManager(viewMenu);
+ if (manager != null) {
+ // remark ourselves as dirty so that the menu will be
+ // reconstructed
+ manager.markDirty();
+ }
+ }
+ return menu.getItemCount() != 0;
+ }
+ return false;
+ }
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ActionBars.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ActionBars.java
index 55dc3433325..999f5b62eb4 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ActionBars.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ActionBars.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2011 IBM Corporation and others.
+ * Copyright (c) 2010, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13,10 +13,12 @@ package org.eclipse.ui.internal.e4.compatibility;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MGenericStack;
+import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
import org.eclipse.e4.ui.widgets.CTabFolder;
+import org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer;
import org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
@@ -110,9 +112,31 @@ public class ActionBars extends SubActionBars {
}
}
}
+
+ MUIElement parent = getParentModel();
+ if (parent != null) {
+ Object renderer = parent.getRenderer();
+ if (renderer instanceof StackRenderer) {
+ StackRenderer stackRenderer = (StackRenderer) renderer;
+ CTabFolder folder = (CTabFolder) parent.getWidget();
+ stackRenderer.disposeViewMenu(folder);
+ stackRenderer.setupMenuButton(part, folder);
+ stackRenderer.layoutTopRight(folder);
+ }
+ }
+
super.updateActionBars();
}
+ private MUIElement getParentModel() {
+ MElementContainer<MUIElement> parent = part.getParent();
+ if (parent == null) {
+ MPlaceholder placeholder = part.getCurSharedRef();
+ return placeholder == null ? null : placeholder.getParent();
+ }
+ return parent;
+ }
+
private Control getPackParent(Control control) {
Composite parent = control.getParent();
while (parent != null) {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/CompatibilityView.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/CompatibilityView.java
index 5ca44fac98e..1b9f8f8b6ed 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/CompatibilityView.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/CompatibilityView.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2011 IBM Corporation and others.
+ * Copyright (c) 2009, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -83,6 +83,15 @@ public class CompatibilityView extends CompatibilityPart {
return reference;
}
+ private MMenu getViewMenu() {
+ for (MMenu menu : part.getMenus()) {
+ if (menu.getTags().contains(StackRenderer.TAG_VIEW_MENU)) {
+ return menu;
+ }
+ }
+ return null;
+ }
+
/*
* (non-Javadoc)
*
@@ -94,6 +103,9 @@ public class CompatibilityView extends CompatibilityPart {
protected boolean createPartControl(IWorkbenchPart legacyPart, Composite parent) {
part.getContext().set(IViewPart.class, (IViewPart) legacyPart);
+ IEclipseContext context = getModel().getContext();
+ IRendererFactory rendererFactory = context.get(IRendererFactory.class);
+
// Some views (i.e. Console) require that the actual ToolBar be
// instantiated before they are
IActionBars actionBars = ((IViewPart) legacyPart).getViewSite().getActionBars();
@@ -101,22 +113,22 @@ public class CompatibilityView extends CompatibilityPart {
Composite toolBarParent = new Composite(parent, SWT.NONE);
tbm.createControl(toolBarParent);
+ MenuManager mm = (MenuManager) actionBars.getMenuManager();
+ MMenu menu = getViewMenu();
+ if (menu != null) {
+ AbstractPartRenderer apr = rendererFactory.getRenderer(menu, parent);
+ if (apr instanceof MenuManagerRenderer) {
+ MenuManagerRenderer renderer = (MenuManagerRenderer) apr;
+ renderer.linkModelToManager(menu, mm);
+ }
+ }
+
super.createPartControl(legacyPart, parent);
// dispose the tb, it will be re-created when the tab is shown
toolBarParent.dispose();
- IEclipseContext context = getModel().getContext();
- IRendererFactory rendererFactory = context.get(IRendererFactory.class);
-
- MenuManager mm = (MenuManager) actionBars.getMenuManager();
- MMenu menu = null;
- for (MMenu me : part.getMenus()) {
- if (me.getTags().contains(StackRenderer.TAG_VIEW_MENU)) {
- menu = me;
- break;
- }
- }
+ menu = getViewMenu();
if (menu == null) {
menu = MenuFactoryImpl.eINSTANCE.createMenu();
menu.setElementId(part.getElementId());

Back to the top