blob: ff71a1aea29bc26763b15ffe790a08ae76fca9ce [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 ALL4TEC & CEA LIST.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ALL4TEC & CEA LIST - initial API and implementation
******************************************************************************/
package org.polarsys.esf.core.common.ui.actions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.emf.edit.ui.action.CreateChildAction;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.SubContributionItem;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchPart;
import org.polarsys.esf.core.common.ui.CommonUIActivator;
/**
* Utility class used to centralise shared constants, and shared methods
* for all the action bar contributors.
*
* @author $Author: jdumont $
* @version $Revision: 83 $
*/
public final class ActionBarContributorUtils {
/** The singleton instance of the utility class. */
public static final ActionBarContributorUtils INSTANCE = new ActionBarContributorUtils();
/** The show properties action id. */
public static final String SHOW_PROPERTIES_ACTION_ID = "show_properties_action"; //$NON-NLS-1$
/** The refresh action id. */
public static final String REFRESH_ACTION_ID = "refresh_action"; //$NON-NLS-1$
/** Id for the collapse all action. */
public static final String COLLAPSE_ALL_ACTION_ID = "action.collapseall.id"; //$NON-NLS-1$
/** Id for the expand all action. */
public static final String EXPAND_ALL_ACTION_ID = "action.expandall.id"; //$NON-NLS-1$
/** The edit separator id. */
public static final String EDIT_SEPARATOR_ID = "edit"; //$NON-NLS-1$
/** The additions separator id. */
public static final String ADDITIONS_SEPARATOR_ID = "additions"; //$NON-NLS-1$
/** The additions end id. */
public static final String ADDITIONS_END_SEPARATOR_ID = "additions-end"; //$NON-NLS-1$
/** The ui actions id. */
public static final String UI_ACTIONS_SEPARATOR_ID = "ui-actions"; //$NON-NLS-1$
/** The create child menu id. */
public static final String CREATECHILD_MENU_ID = "createChildMenu"; //$NON-NLS-1$
/** Separator id, for the toolbar actions linked to the selected element. */
public static final String TOOLBAR_SEP_SELECTION_ACTIONS = "toolbar-selection-actions"; //$NON-NLS-1$
/** Separator id, for the toolbar delete action linked to the selected element. */
public static final String TOOLBAR_SEP_DELETE_ACTION = "toolbar-delete-action"; //$NON-NLS-1$
/** Prefix used to create the id of toolbar actions which create child on the current selection. */
public static final String CREATECHILD_ACTION_ID_PREFIX = "selection.createchild.action."; //$NON-NLS-1$
/** Label for the create child menu. */
public static final String CREATECHILD_MENU_LABEL =
CommonUIActivator.getMessages().getString(
"ActionBarContributorUtils.menu.child.new"); //$NON-NLS-1$
/** Label for the show properties action. */
public static final String SHOW_PROPERTIES_ACTION_LABEL =
CommonUIActivator.getMessages().getString(
"ActionBarContributorUtils.actions.showpropertiesview"); //$NON-NLS-1$
/** Label for the refresh action. */
public static final String REFRESH_ACTION_LABEL =
CommonUIActivator.getMessages().getString(
"ActionBarContributorUtils.actions.refresh"); //$NON-NLS-1$
/** Label for the expand all action. */
public static final String EXPAND_ALL_ACTION_LABEL =
CommonUIActivator.getMessages().getString(
"ActionBarContributorUtils.actions.expandall"); //$NON-NLS-1$
/** Label for the collapse all action. */
public static final String COLLAPSE_ALL_ACTION_LABEL =
CommonUIActivator.getMessages().getString(
"ActionBarContributorUtils.actions.collapseall"); //$NON-NLS-1$
/**
* Private constructor, as it's a utility class.
*/
private ActionBarContributorUtils() {
}
/**
* Generate a {@link CreateChildAction}, to add content under the selection. An action is created
* for each object described by the given <code>descriptors</code>.
*
* The action id is automatically generated, and is prefixed by a custom
* string {@link #CREATECHILD_ACTION_ID_PREFIX}, to be able to find them easily later.
*
* @param pWorkbenchPart The part from which the editing domain will be found, if it's an editing domain provider
* @param pDescriptors The collection of descriptors corresponding to the child which may be created
* @param pSelection The selection containing the object for which the children can be created
* @return The collection of actions created
*/
public Collection<IAction> generateCreateChildActionsCollection(
final IWorkbenchPart pWorkbenchPart,
final Collection<?> pDescriptors,
final ISelection pSelection) {
// Initialise the collection of actions
final Collection<IAction> vActionsCollection = new ArrayList<IAction>();
if (pDescriptors != null) {
int i = 0;
// Loop on the given descriptors to create an action for each one
for (final Object vDescriptor : pDescriptors) {
// Create the action
IAction vCreateChildAction = new CreateChildAction(pWorkbenchPart, pSelection, vDescriptor);
// Set its unique id
vCreateChildAction.setId(
ActionBarContributorUtils.CREATECHILD_ACTION_ID_PREFIX.concat(String.valueOf(i++)));
// Finally add it to the returned collection
vActionsCollection.add(vCreateChildAction);
}
}
return vActionsCollection;
}
/**
* This populates the specified <code>manager</code> with {@link ActionContributionItem}s
* based on the {@link IAction}s contained in the given collection,
* by inserting them before the specified contribution item <code>contributionID</code>.
* If <code>contributionID</code> is <code>null</code>, they are simply added.
*
* @param pManager The contribution manager to populate
* @param pActionsCollection The actions to add in the manager
* @param pContributionID The ID defining where the actions must be inserted. May be null
*/
public void populateManager(
final IContributionManager pManager,
final Collection<? extends IAction> pActionsCollection,
final String pContributionID) {
if (pManager != null && pActionsCollection != null) {
// Loop on the actions to add in the manager
for (final IAction vAction : pActionsCollection) {
if (StringUtils.isNotEmpty(pContributionID)) {
// Insert the action at the right location
pManager.insertBefore(pContributionID, vAction);
} else {
// Simply add the action in the manager
pManager.add(vAction);
}
}
}
}
/**
* This populates the specified <code>manager</code> with {@link MenuManager}s containing
* {@link ActionContributionItem}s based on the {@link IAction}s contained in the given collection,
* by inserting them before the specified contribution item <code>contributionID</code>.
* If <code>contributionID</code> is <code>null</code>, they are simply added.
*
* @param pManager The contribution manager to populate
* @param pSubmenuActionsMap The submenu actions to add in the manager
* @param pContributionID The ID defining where the actions must be inserted. May be null
*/
public void populateManager(
final IContributionManager pManager,
final Map<String, Collection<IAction>> pSubmenuActionsMap,
final String pContributionID) {
if (pManager != null && pSubmenuActionsMap != null) {
// Loop on the submenu action to add in the manager
for (final Map.Entry<String, Collection<IAction>> vSubmenuActionsMapEntry : pSubmenuActionsMap.entrySet()) {
// Create the submenu manager from the map entry key
MenuManager vSubmenuManager = new MenuManager(vSubmenuActionsMapEntry.getKey());
// Add the submenu in the given contribution manager
if (StringUtils.isNotEmpty(pContributionID)) {
// Insert the action at the right location
pManager.insertBefore(pContributionID, vSubmenuManager);
} else {
// Simply add the action in the manager
pManager.add(vSubmenuManager);
}
// Finally populate the submenu with all the linked actions, contained in the map value
populateManager(vSubmenuManager, vSubmenuActionsMapEntry.getValue(), null);
}
}
}
/**
* This removes from the specified <code>manager</code> all {@link ActionContributionItem}s
* based on the {@link IAction}s contained in the given collection.
*
* @param pManager The contribution manager to depopulate
* @param pActionsCollection The actions to remove from the manager
*/
public void depopulateManager(
final IContributionManager pManager,
final Collection<? extends IAction> pActionsCollection) {
if (pManager != null && pActionsCollection != null) {
// Loop on the items currently contained in the contribution manager
for (final IContributionItem vContributionItem : pManager.getItems()) {
// Look into sub-contribution items to find the leaf of the menus
IContributionItem vSubcontributionItem = vContributionItem;
while (vSubcontributionItem instanceof SubContributionItem) {
vSubcontributionItem = ((SubContributionItem) vSubcontributionItem).getInnerItem();
}
// Delete the sub-contribution corresponding to the actions to remove
if (vSubcontributionItem instanceof ActionContributionItem) {
IAction vSubcontributionAction = ((ActionContributionItem) vSubcontributionItem).getAction();
if (pActionsCollection.contains(vSubcontributionAction)) {
pManager.remove(vSubcontributionItem);
}
}
}
}
}
/**
* This removes from the specified <code>manager</code> all {@link MenuManager}s and their
* {@link ActionContributionItem}s based on the {@link IAction}s contained in the given map.
*
* @param pManager The contribution manager to depopulate
* @param pSubmenuActionsMap The submenu actions to remove from the manager
*/
public void depopulateManager(
final IContributionManager pManager,
final Map<String, Collection<IAction>> pSubmenuActionsMap) {
if (pManager != null && pSubmenuActionsMap != null) {
// Loop on the items currently contained in the contribution manager
for (final IContributionItem vContributionItem : pManager.getItems()) {
if (vContributionItem instanceof MenuManager) {
final MenuManager vSubmenuManager = (MenuManager) vContributionItem;
// If the map contains the menu to remove, depopulate the menu and then
// remove it from the parent contribution manager
if (pSubmenuActionsMap.containsKey(vSubmenuManager.getMenuText())) {
depopulateManager(vSubmenuManager, pSubmenuActionsMap.get(vContributionItem));
pManager.remove(vContributionItem);
}
}
}
}
}
/**
* This extracts those actions in the given collection whose text is qualified and returns
* a map of these actions, keyed by submenu text.
*
* @param pActionsCollection The collection of actions for which the submenus must be extracted
* @return The map of extracted submenus, with their text as key and all theirs actions as value
*/
public Map<String, Collection<IAction>> extractSubmenuActions(final Collection<IAction> pActionsCollection) {
// Initialise the map
final Map<String, Collection<IAction>> vExtractedSubmenuActionsMap =
new LinkedHashMap<String, Collection<IAction>>();
if (pActionsCollection != null) {
// Loop on the given actions collection with an iterator as the collection may be modified
Iterator<IAction> vActionsIterator = pActionsCollection.iterator();
while (vActionsIterator.hasNext()) {
// Get the current action
final IAction vAction = vActionsIterator.next();
// Get the action text, to parse it and extract the submenus
// NB : Use an empty String by default to avoid the exception on the tokenizer if null
String vTextToTokenize = StringUtils.EMPTY;
if (StringUtils.isNotEmpty(vAction.getText())) {
vTextToTokenize = vAction.getText();
}
// Parse the action text to find the submenus to create
final StringTokenizer vActionTextTokenizer = new StringTokenizer(vTextToTokenize, "|"); //$NON-NLS-1$
// Ensure that a submenu is needed
if (vActionTextTokenizer.countTokens() == 2) {
// Get the submenu text, and the action text
String vSubMenuText = vActionTextTokenizer.nextToken().trim();
String vActionText = vActionTextTokenizer.nextToken().trim();
// Get the collection of action corresponding to this submenu, to populate it
Collection<IAction> vSubmenuActionsCollection = vExtractedSubmenuActionsMap.get(vSubMenuText);
if (vSubmenuActionsCollection == null) {
// The collection doesn't already exists, thus create it and add it in the map
vSubmenuActionsCollection = new ArrayList<IAction>();
vExtractedSubmenuActionsMap.put(vSubMenuText, vSubmenuActionsCollection);
}
// Then update the current action text and add it in the collection
// of actions associated to the current submenu
vAction.setText(vActionText);
vSubmenuActionsCollection.add(vAction);
// Finally remove the current action
vActionsIterator.remove();
}
}
}
return vExtractedSubmenuActionsMap;
}
}