Ongoing work for bug 168058. Revamp the ToolBar Dropdown menu API,
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java
index 93f3757..dc0bdef 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/MenuAdditionCacheEntry.java
@@ -182,15 +182,13 @@
*/
private IContributionItem createMenuAdditionContribution(
final IConfigurationElement menuAddition) {
- // Is this for a menu or a ToolBar ?
- if (!getLocation().startsWith("toolbar")) //$NON-NLS-1$
- return new MenuManager(getLabel(menuAddition), getId(menuAddition));
-
- // Contribute to a Toolbar...
- return new ToolBarDropDownContributionItem(getId(menuAddition),
- getCommandId(menuAddition), getParameters(menuAddition),
- getIconDescriptor(menuAddition), getLabel(menuAddition),
- getTooltip(menuAddition));
+ // Is this for a menu or a ToolBar ? We can't create
+ // a menu directly under a Toolbar; we have to add an
+ // item of style 'pulldown'
+ if (getLocation().startsWith("toolbar")) //$NON-NLS-1$
+ return null;
+
+ return new MenuManager(getLabel(menuAddition), getId(menuAddition));
}
/**
@@ -272,8 +270,6 @@
getIconDescriptor(itemAddition), null, null,
getLabel(itemAddition), null, getTooltip(itemAddition),
getStyle(itemAddition));
- // return new CommandContributionItem(getId(itemAddition),
- // itemAddition);
}
/*
@@ -345,6 +341,9 @@
if (IWorkbenchRegistryConstants.STYLE_RADIO.equals(style)) {
return CommandContributionItem.STYLE_RADIO;
}
+ if (IWorkbenchRegistryConstants.STYLE_PULLDOWN.equals(style)) {
+ return CommandContributionItem.STYLE_PULLDOWN;
+ }
return CommandContributionItem.STYLE_PUSH;
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/ToolBarDropDownContributionItem.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/ToolBarDropDownContributionItem.java
deleted file mode 100644
index b2d604e..0000000
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/menus/ToolBarDropDownContributionItem.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 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
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- ******************************************************************************/
-package org.eclipse.ui.internal.menus;
-
-import java.util.Map;
-
-import org.eclipse.jface.action.ContributionItem;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.resource.LocalResourceManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-import org.eclipse.swt.widgets.Widget;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.menus.AbstractContributionFactory;
-import org.eclipse.ui.menus.IMenuService;
-
-/**
- * A contribution item which provides drop down menu support specifically for
- * ToolBar drop down menus. It can be used in
- * {@link AbstractContributionFactory#createContributionItems(IMenuService, java.util.List)}.
- * <p>
- * It currently supports placement only in toolbars.
- * </p>
- * <p>
- * This class may be instantiated; it is not intended to be subclassed.
- * </p>
- * <p>
- * <strong>PROVISIONAL</strong>. This class or interface has been added as part
- * of a work in progress. There is a guarantee neither that this API will work
- * nor that it will remain the same. Please do not use this API without
- * consulting with the Platform/UI team.
- * </p>
- *
- * @since 3.3
- */
-public final class ToolBarDropDownContributionItem extends ContributionItem {
- /**
- *
- */
- private LocalResourceManager localResourceManager;
-
- private Listener menuItemListener;
-
- private Widget widget;
-
- //private String commandId;
-
- private ImageDescriptor icon;
-
- private String label;
-
- private String tooltip;
-
- private IMenuService menuService;
-
- private MenuManager menuManager;
-
- private Menu menu = null;
-
- /**
- * Create a ToolBarDropDownConributionItem to place in a ContributionManager.
- * <p>
- * <b>NOTE:</b> The comand part of this contribution is not currently
- * implemented.
- * </p>
- *
- * @param id
- * The id for this item. May be <code>null</code>. Items
- * without an id cannot be referenced later.
- * @param commandId
- * A command id for a defined command. Must not be
- * <code>null</code>.
- * @param parameters
- * A map of strings to strings which represent parameter names to
- * values. The parameter names must match those in the command
- * definition.
- * @param icon
- * An icon for this item. May be <code>null</code>.
- * @param label
- * A label for this item. May be <code>null</code>.
- * @param tooltip
- * A tooltip for this item. May be <code>null</code>. Tooltips
- * are currently only valid for toolbar contributions.
- */
- public ToolBarDropDownContributionItem(String id, String commandId, Map parameters,
- ImageDescriptor icon, String label, String tooltip) {
- super(id);
- //this.commandId = commandId;
- this.icon = icon;
- this.label = label;
- this.tooltip = tooltip;
-
- // Access the menu service
- menuService = (IMenuService) PlatformUI.getWorkbench()
- .getService(IMenuService.class);
-
- // Construct a MenuManager and its menu
- menuManager = new MenuManager(label, getId());
- menuManager.setRemoveAllWhenShown(true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.action.ContributionItem#fill(org.eclipse.swt.widgets.ToolBar,
- * int)
- */
- public void fill(ToolBar parent, int index) {
- ToolItem newItem = new ToolItem(parent, SWT.DROP_DOWN, index);
- newItem.setData(this);
- newItem.setEnabled(isEnabled());
-
- if (icon != null) {
- LocalResourceManager m = new LocalResourceManager(JFaceResources
- .getResources());
- newItem.setImage(m.createImage(icon));
- disposeOldImages();
- localResourceManager = m;
- } else if (label != null) {
- newItem.setText(label);
- }
-
- if (tooltip != null)
- newItem.setToolTipText(tooltip);
- else if (label != null)
- newItem.setToolTipText(label);
-
- newItem.addListener(SWT.Selection, getItemListener());
- newItem.addListener(SWT.Dispose, getItemListener());
-
- widget = newItem;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.action.ContributionItem#update()
- */
- public void update() {
- update(null);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.action.ContributionItem#update(java.lang.String)
- */
- public void update(String id) {
- if (widget != null) {
- if (widget instanceof MenuItem) {
- MenuItem item = (MenuItem) widget;
- if (item.isEnabled() != isEnabled()) {
- item.setEnabled(isEnabled());
- }
- } else if (widget instanceof ToolItem) {
- ToolItem item = (ToolItem) widget;
- if (item.isEnabled() != isEnabled()) {
- item.setEnabled(isEnabled());
- }
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ui.internal.menus.AuthorityContributionItem#dispose()
- */
- public void dispose() {
- disposeOldImages();
- super.dispose();
- }
-
- /**
- *
- */
- private void disposeOldImages() {
- if (localResourceManager != null) {
- localResourceManager.dispose();
- localResourceManager = null;
- }
- }
-
- private Listener getItemListener() {
- if (menuItemListener == null) {
- menuItemListener = new Listener() {
- public void handleEvent(Event event) {
- switch (event.type) {
- case SWT.Dispose:
- handleWidgetDispose(event);
- break;
- case SWT.Selection:
- if (event.widget != null) {
- handleWidgetSelection(event);
- }
- break;
- }
- }
- };
- }
- return menuItemListener;
- }
-
- private void handleWidgetDispose(Event event) {
- if (event.widget == widget) {
- widget.removeListener(SWT.Selection, getItemListener());
- widget.removeListener(SWT.Dispose, getItemListener());
- widget = null;
- dispose();
- }
- }
-
- private void handleWidgetSelection(Event event) {
- Widget item = event.widget;
- if (item != null) {
- int style = item.getStyle();
- if ((style & SWT.DROP_DOWN) != 0) {
- if (event.detail == 4) { // on drop-down button
- ToolItem ti = (ToolItem) item;
-
- // Defer menu creation until the first 'open'
- if (menu == null) {
- menu = menuManager.createContextMenu(ti.getParent());
- menuManager.addMenuListener(new IMenuListener() {
- public void menuAboutToShow(IMenuManager manager) {
- populateMenu();
- }
- });
- }
-
- // position the menu below the drop down item
- Rectangle b = ti.getBounds();
- Point p = ti.getParent().toDisplay(
- new Point(b.x, b.y + b.height));
- menu.setLocation(p.x, p.y); // waiting for SWT
- // 0.42
- menu.setVisible(true);
- return; // we don't fire the action
- }
- }
- // TODO: 'Comand' code goes here...
- }
- }
-
- /**
- * Use the menu service to add any additons into the MenuManager
- */
- private void populateMenu() {
- menuService.populateContributionManager(menuManager, "menu:" + getId()); //$NON-NLS-1$
- }
-
- /**
- * Update the icon on this command contribution item.
- *
- * @param desc
- * The descriptor for the new icon to display.
- */
- public void setIcon(ImageDescriptor desc) {
- icon = desc;
- if (widget instanceof MenuItem) {
- MenuItem item = (MenuItem) widget;
- disposeOldImages();
- if (desc != null) {
- LocalResourceManager m = new LocalResourceManager(
- JFaceResources.getResources());
- item.setImage(m.createImage(desc));
- localResourceManager = m;
- }
- } else if (widget instanceof ToolItem) {
- ToolItem item = (ToolItem) widget;
- disposeOldImages();
- if (desc != null) {
- LocalResourceManager m = new LocalResourceManager(
- JFaceResources.getResources());
- item.setImage(m.createImage(desc));
- localResourceManager = m;
- }
- }
- }
-
- /**
- * Update the label on this command contribution item.
- *
- * @param text
- * The new label to display.
- */
- public void setLabel(String text) {
- label = text;
- if (widget instanceof MenuItem) {
- ((MenuItem) widget).setText(text);
- } else if (widget instanceof ToolItem) {
- ((ToolItem) widget).setText(text);
- }
- }
-
- /**
- * Update the tooltip on this command contribution item. Tooltips are
- * currently only valid for toolbar contributions.
- *
- * @param text
- * The new tooltip to display.
- */
- public void setTooltip(String text) {
- tooltip = text;
- if (widget instanceof ToolItem) {
- ((ToolItem) widget).setToolTipText(text);
- }
- }
-}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/menus/CommandContributionItem.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/menus/CommandContributionItem.java
index 85427c8..1833a7b 100755
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/menus/CommandContributionItem.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/menus/CommandContributionItem.java
@@ -24,10 +24,17 @@
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
@@ -75,6 +82,11 @@
* A radio-button style menu item.
*/
public static final int STYLE_RADIO = SWT.RADIO;
+
+ /**
+ * A ToolBar pulldown item.
+ */
+ public static final int STYLE_PULLDOWN = SWT.DROP_DOWN;
private LocalResourceManager localResourceManager;
@@ -82,6 +94,8 @@
private Widget widget;
+ private IMenuService menuService;
+
private ICommandService commandService;
private IHandlerService handlerService;
@@ -148,8 +162,10 @@
this.mnemonic = mnemonic;
this.tooltip = tooltip;
this.style = style;
+ menuService = (IMenuService) PlatformUI.getWorkbench()
+ .getService(IMenuService.class);
commandService = (ICommandService) PlatformUI.getWorkbench()
- .getService(ICommandService.class);
+ .getService(ICommandService.class);
handlerService = (IHandlerService) PlatformUI.getWorkbench()
.getService(IHandlerService.class);
createCommand(commandId, parameters);
@@ -230,11 +246,16 @@
return;
}
+ // Menus don't support the pulldown style
+ int tmpStyle = style;
+ if (tmpStyle == STYLE_PULLDOWN)
+ tmpStyle = STYLE_PUSH;
+
MenuItem item = null;
if (index >= 0) {
- item = new MenuItem(parent, style, index);
+ item = new MenuItem(parent, tmpStyle, index);
} else {
- item = new MenuItem(parent, style);
+ item = new MenuItem(parent, tmpStyle);
}
item.setData(this);
@@ -411,6 +432,10 @@
}
private void handleWidgetSelection(Event event) {
+ // Special check for ToolBar dropdowns...
+ if (openDropDownMenu(event))
+ return;
+
try {
handlerService.executeCommand(command, event);
} catch (ExecutionException e) {
@@ -428,6 +453,49 @@
}
}
+ /**
+ * Determines if the selection was on the dropdown affordance
+ * and, if so, opens the drop down menu (populated using the
+ * same id as this item...
+ * @param event The <code>SWT.Selection</code> event to be tested
+ *
+ * @return <code>true</code> iff a drop down menu was opened
+ */
+ private boolean openDropDownMenu(Event event) {
+ Widget item = event.widget;
+ if (item != null) {
+ int style = item.getStyle();
+ if ((style & SWT.DROP_DOWN) != 0) {
+ if (event.detail == 4) { // on drop-down button
+ ToolItem ti = (ToolItem) item;
+
+ final MenuManager menuManager = new MenuManager();
+ Menu menu = menuManager.createContextMenu(ti.getParent());
+ menuManager.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ menuService.populateContributionManager(menuManager, "menu:" + getId()); //$NON-NLS-1$
+ }
+ });
+ menu.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ System.out.println("dispose menu"); //$NON-NLS-1$
+ }
+ });
+ // position the menu below the drop down item
+ Rectangle b = ti.getBounds();
+ Point p = ti.getParent().toDisplay(
+ new Point(b.x, b.y + b.height));
+ menu.setLocation(p.x, p.y); // waiting for SWT
+ // 0.42
+ menu.setVisible(true);
+ return true; // we don't fire the action
+ }
+ }
+ }
+
+ return false;
+ }
+
/*
* (non-Javadoc)
*
diff --git a/bundles/org.eclipse.ui/schema/menus.exsd b/bundles/org.eclipse.ui/schema/menus.exsd
index ae5d985..e9154d2 100644
--- a/bundles/org.eclipse.ui/schema/menus.exsd
+++ b/bundles/org.eclipse.ui/schema/menus.exsd
@@ -680,6 +680,10 @@
<td valign="top">- as a checked style menu item or as a toggle tool item. The initial value is specified by the <samp>state</samp> attribute.</td>
</tr>
<tr>
+ <td valign="top" width="25"></td>
+ <td valign="top" nowrap><b>pulldown</b></td>
+ <td valign="top">- (Toolar only) Creates a ToolItem with the <code>SWT.DROP_DOWN</code> affordance. The URI of the menu is "menu:" + this item's ID.</td>
+ </tr>
</table>
</documentation>
</annotation>
@@ -691,6 +695,8 @@
</enumeration>
<enumeration value="toggle">
</enumeration>
+ <enumeration value="pulldown">
+ </enumeration>
</restriction>
</simpleType>
</attribute>
diff --git a/tests/org.eclipse.ui.tests/plugin.xml b/tests/org.eclipse.ui.tests/plugin.xml
index 8beac96..84a5fcd 100644
--- a/tests/org.eclipse.ui.tests/plugin.xml
+++ b/tests/org.eclipse.ui.tests/plugin.xml
@@ -3080,6 +3080,14 @@
</menuContribution>
<menuContribution
+ locationURI="menu:MenuTest.toolbar.DropItem">
+ <item
+ commandId="org.eclipse.ui.tests.menus.enabledWorld"
+ label="Dropdown Item">
+ </item>
+ </menuContribution>
+
+ <menuContribution
locationURI="toolbar:org.eclipse.ui.tests.api.MenuTestHarness">
<item
commandId="org.eclipse.ui.tests.menus.toggleContext"
@@ -3104,15 +3112,14 @@
class="org.eclipse.ui.tests.api.workbenchpart.TextWidget"
id="MenuTest.popup.BasicWidgetItem">
</widget>
- <menu
- icon="icons/binary_co.gif"
- id="MenuTest.popup.BasicMenuItem"
- label="Basic Menu">
- <item
- commandId="org.eclipse.ui.tests.menus.enabledWorld"
- label="Sub Item">
- </item>
- </menu>
+ <item
+ commandId="org.eclipse.ui.tests.menus.enabledWorld"
+ icon="icons/anything.gif"
+ id="MenuTest.toolbar.DropItem"
+ label="Toolbar Dropdown"
+ style="pulldown"
+ mnemonic="D">
+ </item>
<separator
name="MenuTest.Advanced"
visible="true">