Bug 319319 Window menu lists too many top-level windows
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/RenderedMenuItemRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/RenderedMenuItemRenderer.java
index 24effc9..7d1b113 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/RenderedMenuItemRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/RenderedMenuItemRenderer.java
@@ -10,12 +10,20 @@
*******************************************************************************/
package org.eclipse.e4.ui.workbench.renderers.swt;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
import org.eclipse.e4.ui.internal.workbench.ExtensionPointProxy;
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.menu.MMenuElement;
import org.eclipse.e4.ui.model.application.ui.menu.MRenderedMenuItem;
+import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Widget;
@@ -25,6 +33,27 @@
*/
public class RenderedMenuItemRenderer extends SWTPartRenderer {
+ private static Method aboutToShow;
+
+ private static Method getAboutToShow() {
+ if (aboutToShow == null) {
+ try {
+ aboutToShow = MenuManager.class
+ .getDeclaredMethod("handleAboutToShow"); //$NON-NLS-1$
+ aboutToShow.setAccessible(true);
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchMethodException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return aboutToShow;
+ }
+
+ private Map<IContributionItem, List<MenuRecord>> map = new WeakHashMap<IContributionItem, List<MenuRecord>>();
+
public Object createWidget(final MUIElement element, Object parent) {
if (!(element instanceof MRenderedMenuItem)
|| !(parent instanceof Menu)) {
@@ -47,13 +76,81 @@
}
private Object fill(IContributionItem item, Menu menu) {
- int index = menu.getItemCount();
- item.fill(menu, index);
-
- if (index == menu.getItemCount()) {
+ ContributionItem contribution = (ContributionItem) item;
+ MenuManager manager = (MenuManager) contribution.getParent();
+ try {
+ if (manager == null) {
+ manager = new MenuManager();
+ manager.add(contribution);
+ }
+ getAboutToShow().invoke(manager, new Object[0]);
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return null;
+ } catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return null;
+ } catch (InvocationTargetException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
return null;
}
- return menu.getItem(index);
+
+ int itemCount = menu.getItemCount();
+ List<MenuRecord> list = map.get(item);
+ if (list != null) {
+ for (int i = 0; i < list.size(); i++) {
+ MenuRecord record = list.get(i);
+ Menu storedMenu = record.getMenu();
+ if (storedMenu.isDisposed()) {
+ list.remove(i);
+ i--;
+ } else if (storedMenu == menu) {
+ record.dispose();
+ itemCount = menu.getItemCount();
+ list.remove(i);
+ break;
+ }
+ }
+ }
+
+ item.fill(menu, itemCount);
+ int endIndex = menu.getItemCount();
+
+ if (list == null) {
+ if (itemCount != endIndex) {
+ list = new ArrayList<MenuRecord>();
+ MenuRecord record = new MenuRecord(menu);
+ for (int i = itemCount; i < endIndex; i++) {
+ record.addItem(menu.getItem(i));
+ }
+ list.add(record);
+ map.put(item, list);
+ }
+ } else {
+ for (int i = 0; i < list.size(); i++) {
+ MenuRecord record = list.get(i);
+ if (record.getMenu() == menu) {
+ list.remove(i);
+ record = new MenuRecord(menu);
+ for (int j = itemCount; j < endIndex; j++) {
+ record.addItem(menu.getItem(j));
+ }
+ list.add(record);
+ return null;
+ }
+ }
+
+ MenuRecord record = new MenuRecord(menu);
+ for (int i = itemCount; i < endIndex; i++) {
+ record.addItem(menu.getItem(i));
+ }
+ list.add(record);
+ map.put(item, list);
+ }
+ return null;
}
/*
@@ -134,4 +231,28 @@
// We've delegated further rendering to the ContributionManager
// it's their fault the menu items don't show up!
}
+
+ class MenuRecord {
+
+ private Menu menu;
+ private List<MenuItem> items = new ArrayList<MenuItem>();
+
+ public MenuRecord(Menu menu) {
+ this.menu = menu;
+ }
+
+ public Menu getMenu() {
+ return menu;
+ }
+
+ public void addItem(MenuItem item) {
+ items.add(item);
+ }
+
+ public void dispose() {
+ for (MenuItem item : items) {
+ item.dispose();
+ }
+ }
+ }
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/CompoundContributionItem.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/CompoundContributionItem.java
index 227969d..50e0f26 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/CompoundContributionItem.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/actions/CompoundContributionItem.java
@@ -68,6 +68,9 @@
}
IContributionItem[] items = getContributionItemsToFill();
+ if (index > menu.getItemCount()) {
+ index = menu.getItemCount();
+ }
for (int i = 0; i < items.length; i++) {
IContributionItem item = items[i];
int oldItemCount = menu.getItemCount();