/*******************************************************************************
* Copyright (c) 2012, 2017 Original authors 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:
* Original authors and others - initial API and implementation
* Dirk Fauth <dirk.fauth@googlemail.com> - Bug 451490, 453219
* Roman Flueckiger <roman.flueckiger@mac.com> - Bug 451490
* Thanh Liem PHAN (ALL4TEC) <thanhliem.phan@all4tec.net> - Bug 509361
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.ui.menu;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.export.ExportConfigAttributes;
import org.eclipse.nebula.widgets.nattable.export.command.ExportTableCommandHandler;
import org.eclipse.nebula.widgets.nattable.export.image.ImageExporter;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.ui.NatEventData;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
/**
* This class is used to create a context menu.
*/
public class PopupMenuBuilder {
public static final String HIDE_COLUMN_MENU_ITEM_ID = "hideColumnMenuItem"; //$NON-NLS-1$
public static final String SHOW_ALL_COLUMNS_MENU_ITEM_ID = "showAllColumnsMenuItem"; //$NON-NLS-1$
public static final String HIDE_ROW_MENU_ITEM_ID = "hideRowMenuItem"; //$NON-NLS-1$
public static final String SHOW_ALL_ROWS_MENU_ITEM_ID = "showAllRowsMenuItem"; //$NON-NLS-1$
public static final String AUTO_RESIZE_COLUMN_MENU_ITEM_ID = "autoResizeColumnMenuItem"; //$NON-NLS-1$
public static final String AUTO_RESIZE_ROW_MENU_ITEM_ID = "autoResizeRowMenuItem"; //$NON-NLS-1$
public static final String AUTO_RESIZE_ALL_SELECTED_COLUMN_MENU_ITEM_ID = "autoResizeAllSelectedColumnMenuItem"; //$NON-NLS-1$
public static final String COLUMN_CHOOSER_MENU_ITEM_ID = "columnChooserMenuItem"; //$NON-NLS-1$
public static final String COLUMN_STYLE_EDITOR_MENU_ITEM_ID = "columnStyleEditorMenuItem"; //$NON-NLS-1$
public static final String COLUMN_RENAME_MENU_ITEM_ID = "columnRenameMenuItem"; //$NON-NLS-1$
public static final String CREATE_COLUMN_GROUP_MENU_ITEM_ID = "createColumnGroupMenuItem"; //$NON-NLS-1$
public static final String RENAME_COLUMN_GROUP_MENU_ITEM_ID = "renameColumnGroupMenuItem"; //$NON-NLS-1$
public static final String REMOVE_COLUMN_GROUP_MENU_ITEM_ID = "removeColumnGroupMenuItem"; //$NON-NLS-1$
public static final String UNGROUP_COLUMNS_MENU_ITEM_ID = "ungroupColumnsMenuItem"; //$NON-NLS-1$
public static final String INSPECT_LABEL_MENU_ITEM_ID = "inspectLabelMenuItem"; //$NON-NLS-1$
public static final String CATEGORIES_BASED_COLUMN_CHOOSER_MENU_ITEM_ID = "categoriesBasedColumnChooserMenuItem"; //$NON-NLS-1$
public static final String CLEAR_ALL_FILTERS_MENU_ITEM_ID = "clearAllFiltersMenuItem"; //$NON-NLS-1$
public static final String TOGGLE_FILTER_ROW_MENU_ITEM_ID = "toggleFilterRowMenuItem"; //$NON-NLS-1$
public static final String STATE_MANAGER_MENU_ITEM_ID = "stateManagerMenuItem"; //$NON-NLS-1$
public static final String SEPARATOR_MENU_ITEM_ID = "separatorMenuItem"; //$NON-NLS-1$
/**
* @since 1.5
*/
public static final String EXPORT_IMAGE_MENU_ITEM_ID = "exportImageMenuItem"; //$NON-NLS-1$
/**
* The active NatTable instance the context menu should be added to. Needed
* in advance to be able to add custom menu items that need the NatTable
* instance.
*/
protected NatTable natTable;
/**
* The {@link Menu} that is created with this popup menu builder.
*/
protected Menu popupMenu;
/**
* The {@link MenuManager} that is used by this popup menu builder. Can be
* <code>null</code> if plain SWT menu mechanisms are used.
*/
protected MenuManager menuManager;
/**
* Collection of all registered visibility state checkers for configured
* id's.
*/
protected final MenuItemStateMap visibility = new MenuItemStateMap();
/**
* Collection of all registered enablement state checkers for configured
* id's.
*/
protected final MenuItemStateMap enablement = new MenuItemStateMap();
/**
* Creates {@link PopupMenuBuilder} that builds up a new {@link Menu} that
* is only configurable with this instance of {@link PopupMenuBuilder}. Uses
* a {@link MenuManager} internally to be able to configure visibility and
* enabled states.
*
* @param parent
* The active NatTable instance the context menu should be added
* to.
*/
public PopupMenuBuilder(NatTable parent) {
this(parent, new MenuManager());
}
/**
* Creates a {@link PopupMenuBuilder} that builds up a new {@link Menu}
* using the given {@link MenuManager}.
*
* @param parent
* The active NatTable instance the context menu should be added
* to.
* @param manager
* The {@link MenuManager} that should be used to create the
* {@link Menu}.
*/
public PopupMenuBuilder(NatTable parent, MenuManager manager) {
this.natTable = parent;
this.menuManager = manager;
this.popupMenu = manager.createContextMenu(this.natTable);
}
/**
* Creates a popup menu builder based on the given menu. Using this enables
* the possibility to use configured context menus from plugin.xml and
* adding NatTable commands programmatically.
* <p>
* As an example you might want to create a PopupMenuBuilder by using a
* configured menu with the id
* <i>org.eclipse.nebula.widgets.nattable.example.contextmenu</i>
* <p>
*
* <pre>
* ISelectionProvider isp =
* new RowSelectionProvider<?>(selectionLayer, bodyDataProvider, false);
* MenuManager menuManager = new MenuManager();
* menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
* getSite().registerContextMenu(
* "org.eclipse.nebula.widgets.nattable.example.contextmenu", menuManager, isp);
* PopupMenuBuilder popupMenu =
* new PopupMenuBuilder(menuManager.createContextMenu(natTable));
* </pre>
* <p>
* For usage with Eclipse 4 you can use the <code>EMenuService</code> to
* register the menu to a NatTable instance. Afterwards get the menu and
* remove it from the NatTable to avoid the SWT control menu. The generated
* menu carries a {@link MenuManager} in the {@link Menu#getData()} which
* will be used within this {@link PopupMenuBuilder}.
* </p>
*
* <pre>
* menuService.registerContextMenu(natTable, menuId);
* Menu swtMenu = natTable.getMenu();
* natTable.setMenu(null);
* </pre>
*
* @param natTable
* The active NatTable instance which might be needed for
* creation of menu items that need the NatTable instance to
* work.
* @param menu
* The registered context menu.
*/
public PopupMenuBuilder(NatTable natTable, Menu menu) {
this.natTable = natTable;
this.popupMenu = menu;
// if the menu is build up using a MenuManager, remember that for
// further use
Object mgr = menu.getData("org.eclipse.jface.action.MenuManager.managerKey"); //$NON-NLS-1$
if (mgr != null && mgr instanceof MenuManager) {
this.menuManager = (MenuManager) mgr;
}
}
/**
* Adds the menu item provided by the given {@link IMenuItemProvider} to the
* popup menu. You can use this to add your own item to the popup menu.
* <p>
* Items added by this method can not be identified by id, so adding visible
* or enabled state checkers is not possible for these providers.
* </p>
*
* @param menuItemProvider
* The {@link IMenuItemProvider} that provides the menu item that
* should be added to the popup menu.
* @return The current {@link PopupMenuBuilder} with the added item.
*/
public PopupMenuBuilder withMenuItemProvider(IMenuItemProvider menuItemProvider) {
if (this.menuManager == null) {
menuItemProvider.addMenuItem(this.natTable, this.popupMenu);
} else {
this.menuManager.add(new PopupContributionItem(menuItemProvider));
}
return this;
}
/**
* Adds the menu item provided by the given {@link IMenuItemProvider} to the
* popup menu. You can use this to add your own item to the popup menu.
* <p>
* As items added by this method can be identified via the given id it is
* possible to register visible or enabled state checkers for these
* providers.
* </p>
*
* @param id
* The id under which the given {@link IMenuItemProvider} should
* be identifiable.
* @param menuItemProvider
* The {@link IMenuItemProvider} that provides the menu item that
* should be added to the popup menu.
* @return The current {@link PopupMenuBuilder} with the added item.
*/
public PopupMenuBuilder withMenuItemProvider(String id, IMenuItemProvider menuItemProvider) {
if (this.menuManager == null) {
menuItemProvider.addMenuItem(this.natTable, this.popupMenu);
} else {
this.menuManager.add(new PopupContributionItem(id, menuItemProvider));
}
return this;
}
/**
* Adds the menu item(s) provided by the given {@link ContributionItem} to
* the popup menu. You can use this to add your own item to the popup menu.
* <p>
* This method is only working if the {@link PopupMenuBuilder} is using a
* {@link MenuManager}.
* </p>
* <p>
* Using this adds support for visibility and enabled states of menu items.
* </p>
*
* @param contributionItem
* The {@link ContributionItem} that is used to add a menu item
* to the menu.
* @return The current {@link PopupMenuBuilder} with the added item.
* @throws IllegalStateException
* if this {@link PopupMenuBuilder} does not use a
* {@link MenuManager}
*/
public PopupMenuBuilder withContributionItem(ContributionItem contributionItem) {
if (this.menuManager == null) {
throw new IllegalStateException("This PopupMenuBuilder is not created using a MenuManager, " //$NON-NLS-1$
+ "therefore ContributionItems can not be added"); //$NON-NLS-1$
} else {
this.menuManager.add(contributionItem);
}
return this;
}
/**
* Adds the menu item for hiding a column to the popup menu. Uses the
* default text localized in NatTable core resource bundles.
*
* @return The {@link PopupMenuBuilder} with the hide column menu item
* added.
* @see MenuItemProviders#hideColumnMenuItemProvider()
*/
public PopupMenuBuilder withHideColumnMenuItem() {
return withMenuItemProvider(
HIDE_COLUMN_MENU_ITEM_ID,
MenuItemProviders.hideColumnMenuItemProvider());
}
/**
* Adds the menu item for hiding a column to the popup menu. Uses the given
* String as label for the menu item.
*
* @param menuLabel
* The label to use for showing the item in the popup menu.
* @return The {@link PopupMenuBuilder} with the hide column menu item
* added.
* @see MenuItemProviders#hideColumnMenuItemProvider(String)
*/
public PopupMenuBuilder withHideColumnMenuItem(String menuLabel) {
return withMenuItemProvider(
HIDE_COLUMN_MENU_ITEM_ID,
MenuItemProviders.hideColumnMenuItemProvider(menuLabel));
}
/**
* Adds the menu item for showing all columns to the popup menu. Uses the
* default text localized in NatTable core resource bundles.
*
* @return The {@link PopupMenuBuilder} with the show all columns menu item
* added.
* @see MenuItemProviders#showAllColumnsMenuItemProvider()
*/
public PopupMenuBuilder withShowAllColumnsMenuItem() {
return withMenuItemProvider(
SHOW_ALL_COLUMNS_MENU_ITEM_ID,
MenuItemProviders.showAllColumnsMenuItemProvider());
}
/**
* Adds the menu item for showing all columns to the popup menu. Uses the
* given String as label for the menu item.
*
* @param menuLabel
* The label to use for showing the item in the popup menu.
* @return The {@link PopupMenuBuilder} with the show all columns menu item
* added.
* @see MenuItemProviders#showAllColumnsMenuItemProvider(String)
*/
public PopupMenuBuilder withShowAllColumnsMenuItem(String menuLabel) {
return withMenuItemProvider(
SHOW_ALL_COLUMNS_MENU_ITEM_ID,
MenuItemProviders.showAllColumnsMenuItemProvider(menuLabel));
}
/**
* Add the menu item for exporting to image to the popup menu. Use the
* default text localized in NatTable core resource bundles.
*
* <p>
* <b>IMPORTANT:</b> the {@link ImageExporter} needs to be configured for
* the configuration attribute {@link ExportConfigAttributes#TABLE_EXPORTER}
* to really export to an image. Also the {@link ExportTableCommandHandler}
* needs to be registered on an {@link ILayer} in the layer stack, e.g. the
* GridLayer.
* </p>
*
* @return The {@link PopupMenuBuilder} with the export to image menu item
* added.
* @see MenuItemProviders#exportToImageMenuItemProvider()
* @since 1.5
*/
public PopupMenuBuilder withExportToImageMenuItem() {
return withMenuItemProvider(
EXPORT_IMAGE_MENU_ITEM_ID,
MenuItemProviders.exportToImageMenuItemProvider());
}
/**
* Add the menu item for exporting to image to the popup menu. Use the given
* String as label for the menu item.
*
* <p>
* <b>IMPORTANT:</b> the {@link ImageExporter} needs to be configured for
* the configuration attribute {@link ExportConfigAttributes#TABLE_EXPORTER}
* to really export to an image. Also the {@link ExportTableCommandHandler}
* needs to be registered on an {@link ILayer} in the layer stack, e.g. the
* GridLayer.
* </p>
*
* @param menuLabel
* The label to use for exporting to image in the popup menu.
* @return The {@link PopupMenuBuilder} with the exporting to image menu
* item added.
* @see MenuItemProviders#exportToImageMenuItemProvider(String)
* @since 1.5
*/
public PopupMenuBuilder withExportToImageMenuItem(String menuLabel) {
return withMenuItemProvider(
EXPORT_IMAGE_MENU_ITEM_ID,
MenuItemProviders.exportToImageMenuItemProvider(menuLabel));
}
/**
* Adds the menu item for hiding a row to the popup menu. Uses the default
* text localized in NatTable core resource bundles.
*
* @return The {@link PopupMenuBuilder} with the hide row menu item added.
* @see MenuItemProviders#hideRowMenuItemProvider()
*/
public PopupMenuBuilder withHideRowMenuItem() {
return withMenuItemProvider(
HIDE_ROW_MENU_ITEM_ID,
MenuItemProviders.hideRowMenuItemProvider());
}
/**
* Adds the menu item for hiding a row to the popup menu. Uses the given
* String as label for the menu item.
*
* @param menuLabel
* The label to use for showing the item in the popup menu.
* @return The {@link PopupMenuBuilder} with the hide row menu item added.
* @see MenuItemProviders#hideRowMenuItemProvider(String)
*/
public PopupMenuBuilder withHideRowMenuItem(String menuLabel) {
return withMenuItemProvider(
HIDE_ROW_MENU_ITEM_ID,
MenuItemProviders.hideRowMenuItemProvider(menuLabel));
}
/**
* Adds the menu item for showing all rows to the popup menu. Uses the
* default text localized in NatTable core resource bundles.
*
* @return The {@link PopupMenuBuilder} with the show all rows menu item
* added.
* @see MenuItemProviders#showAllRowsMenuItemProvider()
*/
public PopupMenuBuilder withShowAllRowsMenuItem() {
return withMenuItemProvider(
SHOW_ALL_ROWS_MENU_ITEM_ID,
MenuItemProviders.showAllRowsMenuItemProvider());
}
/**
* Adds the menu item for showing all rows to the popup menu. Uses the given
* String as label for the menu item.
*
* @param menuLabel
* The label to use for showing the item in the popup menu.
* @return The {@link PopupMenuBuilder} with the show all rows menu item
* added.
* @see MenuItemProviders#showAllRowsMenuItemProvider(String)
*/
public PopupMenuBuilder withShowAllRowsMenuItem(String menuLabel) {
return withMenuItemProvider(
SHOW_ALL_ROWS_MENU_ITEM_ID,
MenuItemProviders.showAllRowsMenuItemProvider(menuLabel));
}
/**
* Adds the menu item for auto resizing selected columns to the popup menu.
* Uses the default text localized in NatTable core resource bundles.
*
* @return The {@link PopupMenuBuilder} with the resize selected columns
* menu item added.
* @see MenuItemProviders#autoResizeColumnMenuItemProvider()
*/
public PopupMenuBuilder withAutoResizeSelectedColumnsMenuItem() {
return withMenuItemProvider(
AUTO_RESIZE_COLUMN_MENU_ITEM_ID,
MenuItemProviders.autoResizeColumnMenuItemProvider());
}
/**
* Adds the menu item for auto resizing selected columns to the popup menu.
* Uses the given String as label for the menu item.
*
* @return The {@link PopupMenuBuilder} with the resize selected columns
* menu item added.
* @see MenuItemProviders#autoResizeColumnMenuItemProvider(String)
*/
public PopupMenuBuilder withAutoResizeSelectedColumnsMenuItem(String menuLabel) {
return withMenuItemProvider(
AUTO_RESIZE_COLUMN_MENU_ITEM_ID,
MenuItemProviders.autoResizeColumnMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withAutoResizeSelectedRowsMenuItem() {
return withMenuItemProvider(
AUTO_RESIZE_ROW_MENU_ITEM_ID,
MenuItemProviders.autoResizeRowMenuItemProvider());
}
public PopupMenuBuilder withAutoResizeSelectedRowsMenuItem(String menuLabel) {
return withMenuItemProvider(
AUTO_RESIZE_ROW_MENU_ITEM_ID,
MenuItemProviders.autoResizeRowMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withColumnChooserMenuItem() {
return withMenuItemProvider(
COLUMN_CHOOSER_MENU_ITEM_ID,
MenuItemProviders.columnChooserMenuItemProvider());
}
public PopupMenuBuilder withColumnChooserMenuItem(String menuLabel) {
return withMenuItemProvider(
COLUMN_CHOOSER_MENU_ITEM_ID,
MenuItemProviders.columnChooserMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withColumnStyleEditor() {
return withMenuItemProvider(
COLUMN_STYLE_EDITOR_MENU_ITEM_ID,
MenuItemProviders.columnStyleEditorMenuItemProvider());
}
public PopupMenuBuilder withColumnStyleEditor(String menuLabel) {
return withMenuItemProvider(
COLUMN_STYLE_EDITOR_MENU_ITEM_ID,
MenuItemProviders.columnStyleEditorMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withColumnRenameDialog() {
return withMenuItemProvider(
COLUMN_RENAME_MENU_ITEM_ID,
MenuItemProviders.renameColumnMenuItemProvider());
}
public PopupMenuBuilder withColumnRenameDialog(String menuLabel) {
return withMenuItemProvider(
COLUMN_RENAME_MENU_ITEM_ID,
MenuItemProviders.renameColumnMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withCreateColumnGroupsMenuItem() {
return withMenuItemProvider(
CREATE_COLUMN_GROUP_MENU_ITEM_ID,
MenuItemProviders.createColumnGroupMenuItemProvider());
}
public PopupMenuBuilder withCreateColumnGroupsMenuItem(String menuLabel) {
return withMenuItemProvider(
CREATE_COLUMN_GROUP_MENU_ITEM_ID,
MenuItemProviders.createColumnGroupMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withUngroupColumnsMenuItem() {
return withMenuItemProvider(
UNGROUP_COLUMNS_MENU_ITEM_ID,
MenuItemProviders.ungroupColumnsMenuItemProvider());
}
public PopupMenuBuilder withUngroupColumnsMenuItem(String menuLabel) {
return withMenuItemProvider(
UNGROUP_COLUMNS_MENU_ITEM_ID,
MenuItemProviders.ungroupColumnsMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withRenameColumnGroupMenuItem() {
return withMenuItemProvider(
RENAME_COLUMN_GROUP_MENU_ITEM_ID,
MenuItemProviders.renameColumnGroupMenuItemProvider());
}
public PopupMenuBuilder withRenameColumnGroupMenuItem(String menuLabel) {
return withMenuItemProvider(
RENAME_COLUMN_GROUP_MENU_ITEM_ID,
MenuItemProviders.renameColumnGroupMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withRemoveColumnGroupMenuItem() {
return withMenuItemProvider(
REMOVE_COLUMN_GROUP_MENU_ITEM_ID,
MenuItemProviders.removeColumnGroupMenuItemProvider());
}
public PopupMenuBuilder withRemoveColumnGroupMenuItem(String menuLabel) {
return withMenuItemProvider(
REMOVE_COLUMN_GROUP_MENU_ITEM_ID,
MenuItemProviders.removeColumnGroupMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withInspectLabelsMenuItem() {
return withMenuItemProvider(
INSPECT_LABEL_MENU_ITEM_ID,
MenuItemProviders.inspectLabelsMenuItemProvider());
}
public PopupMenuBuilder withCategoriesBasedColumnChooser() {
return withMenuItemProvider(
CATEGORIES_BASED_COLUMN_CHOOSER_MENU_ITEM_ID,
MenuItemProviders.categoriesBasedColumnChooserMenuItemProvider());
}
public PopupMenuBuilder withCategoriesBasedColumnChooser(String menuLabel) {
return withMenuItemProvider(
CATEGORIES_BASED_COLUMN_CHOOSER_MENU_ITEM_ID,
MenuItemProviders.categoriesBasedColumnChooserMenuItemProvider(menuLabel));
}
public PopupMenuBuilder withClearAllFilters() {
return withMenuItemProvider(
CLEAR_ALL_FILTERS_MENU_ITEM_ID,
MenuItemProviders.clearAllFiltersMenuItemProvider());
}
public PopupMenuBuilder withClearAllFilters(String menuLabel) {
return withMenuItemProvider(
CLEAR_ALL_FILTERS_MENU_ITEM_ID,
MenuItemProviders.clearAllFiltersMenuItemProvider(menuLabel));
}
/**
* Adds a menu item for toggling the visibility of the filter row. Uses the
* default text localized in NatTable core resource bundles.
*
* @return The {@link PopupMenuBuilder} with the toggle filter row menu item
* added.
* @see MenuItemProviders#clearToggleFilterRowMenuItemProvider()
*/
public PopupMenuBuilder withToggleFilterRow() {
return withMenuItemProvider(
TOGGLE_FILTER_ROW_MENU_ITEM_ID,
MenuItemProviders.clearToggleFilterRowMenuItemProvider());
}
/**
* Adds a menu item for toggling the visibility of the filter row. Uses the
* given String as label for the menu item.
*
* @param menuLabel
* The label to use for showing the item in the popup menu.
* @return The {@link PopupMenuBuilder} with the toggle filter row menu item
* added.
* @see MenuItemProviders#clearToggleFilterRowMenuItemProvider(String)
*/
public PopupMenuBuilder withToggleFilterRow(String menuLabel) {
return withMenuItemProvider(
TOGGLE_FILTER_ROW_MENU_ITEM_ID,
MenuItemProviders.clearToggleFilterRowMenuItemProvider(menuLabel));
}
/**
* Adds the menu item for opening the view management dialog to the popup
* menu. Uses the default text localized in NatTable core resource bundles.
* Uses the given String as label for the menu item.
*
* @return The {@link PopupMenuBuilder} with the menu item added for showing
* the view management dialog for managing NatTable states.
* @see MenuItemProviders#stateManagerMenuItemProvider()
*/
public PopupMenuBuilder withStateManagerMenuItemProvider() {
return withMenuItemProvider(
STATE_MANAGER_MENU_ITEM_ID,
MenuItemProviders.stateManagerMenuItemProvider());
}
/**
* Adds the menu item for opening the view management dialog to the popup
* menu.
*
* @param menuLabel
* The label to use for showing the item in the popup menu.
* @return The {@link PopupMenuBuilder} with the menu item added for showing
* the view management dialog for managing NatTable states.
* @see MenuItemProviders#stateManagerMenuItemProvider(String)
*/
public PopupMenuBuilder withStateManagerMenuItemProvider(String menuLabel) {
return withMenuItemProvider(
STATE_MANAGER_MENU_ITEM_ID,
MenuItemProviders.stateManagerMenuItemProvider(menuLabel));
}
/**
* Adds a separator to the popup menu.
*
* @return The {@link PopupMenuBuilder} with an added separator.
* @see MenuItemProviders#separatorMenuItemProvider()
*/
public PopupMenuBuilder withSeparator() {
int count = 0;
if (this.menuManager != null) {
for (IContributionItem item : this.menuManager.getItems()) {
if (item.getId() != null && item.getId().startsWith(SEPARATOR_MENU_ITEM_ID)) {
count++;
}
}
}
return withSeparator(SEPARATOR_MENU_ITEM_ID + "." + count); //$NON-NLS-1$
}
/**
* Adds a separator to the popup menu with the given id.
*
* @param id
* The id to identify the separator. Necessary if there should be
* visibility constraints for specific separators.
* @return The {@link PopupMenuBuilder} with an added separator.
* @see MenuItemProviders#separatorMenuItemProvider()
*/
public PopupMenuBuilder withSeparator(String id) {
return withMenuItemProvider(id, MenuItemProviders.separatorMenuItemProvider());
}
/**
* Builds and returns the created {@link Menu}.
* <p>
* <b>Note:</b> Calling this method will also add a {@link DisposeListener}
* to the NatTable instance to ensure the created {@link Menu} is disposed
* when the NatTable itself gets disposed.
* </p>
*
* @return The {@link Menu} that is created by this builder.
*/
public Menu build() {
this.natTable.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (PopupMenuBuilder.this.popupMenu != null
&& !PopupMenuBuilder.this.popupMenu.isDisposed())
PopupMenuBuilder.this.popupMenu.dispose();
}
});
return this.popupMenu;
}
/**
* Associate a visibility {@link IMenuItemState} with the menu item
* identified by the given id.
* <p>
* The visibility state is handled by the internal {@link MenuManager}. If
* no {@link MenuManager} is used, this method will have not effect.
* </p>
* <p>
* For the item to be visible, all associated {@link IMenuItemState} must be
* active OR no {@link IMenuItemState} must be associated with the item.
* </p>
*
* @param id
* the registered {@link IMenuItemState} will affect the menu
* item identified by the given id.
* @param state
* the {@link IMenuItemState} to queried for the visibility state
* of the menu item with the given id.
* @return This {@link PopupMenuBuilder} with the visible state checker for
* the given id.
*/
public PopupMenuBuilder withVisibleState(String id, IMenuItemState state) {
this.visibility.addMenuItemState(id, state);
return this;
}
/**
* Associate a enabled {@link IMenuItemState} with the menu item identified
* by the given id.
* <p>
* The enabled state is handled by the internal {@link MenuManager}. If no
* {@link MenuManager} is used, this method will have not effect.
* </p>
* <p>
* For the item to be enabled, all associated {@link IMenuItemState} must be
* active OR no {@link IMenuItemState} must be associated with the item.
* </p>
*
* @param id
* the registered {@link IMenuItemState} will affect the menu
* item identified by the given id.
* @param state
* the {@link IMenuItemState} to queried for the enabled state of
* the menu item with the given id.
* @return This {@link PopupMenuBuilder} with the enabled state checker for
* the given id.
*/
public PopupMenuBuilder withEnabledState(String id, IMenuItemState state) {
this.enablement.addMenuItemState(id, state);
return this;
}
/**
* Wrapper class to build up a {@link ContributionItem} based on a given
* {@link IMenuItemProvider}. If an id is set it is possible to register
* state checkers for enabled and visible state.
*/
protected class PopupContributionItem extends ContributionItem {
private IMenuItemProvider provider;
public PopupContributionItem(IMenuItemProvider provider) {
this(null, provider);
}
public PopupContributionItem(String id, IMenuItemProvider provider) {
super(id);
this.provider = provider;
}
@Override
public void fill(Menu menu, int index) {
List<MenuItem> beforeItems = Arrays.asList(menu.getItems());
this.provider.addMenuItem(PopupMenuBuilder.this.natTable, menu);
MenuItem[] afterItems = menu.getItems();
for (MenuItem item : afterItems) {
if (!beforeItems.contains(item)) {
// isEnabled() seems to be not called by the framework on
// opening a menu therefore we set it ourself. For this we
// also need to ensure isDynamic() returns true for
// re-rendering.
item.setEnabled(isEnabled());
}
}
}
@Override
public boolean isDynamic() {
return (getId() != null);
}
@Override
public boolean isEnabled() {
if (getId() != null) {
Object eventData = PopupMenuBuilder.this.popupMenu.getData(MenuItemProviders.NAT_EVENT_DATA_KEY);
if (eventData != null && eventData instanceof NatEventData) {
return PopupMenuBuilder.this.enablement.isActive(getId(), (NatEventData) eventData);
}
}
return true;
}
@Override
public boolean isVisible() {
if (getId() != null) {
Object eventData = PopupMenuBuilder.this.popupMenu.getData(MenuItemProviders.NAT_EVENT_DATA_KEY);
if (eventData != null && eventData instanceof NatEventData) {
return PopupMenuBuilder.this.visibility.isActive(getId(), (NatEventData) eventData);
}
}
return true;
}
}
}