blob: 663b4191b5e9353a5a0e5b6312b09fbe031f1e46 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.ArrayList;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.jface.action.*;
import org.eclipse.ui.*;
/**
* This builder reads the actions for an action set from the registry.
*/
public class PluginActionSetBuilder extends PluginActionBuilder {
public static final String TAG_ACTION_SET = "actionSet"; //$NON-NLS-1$
// As of 2.1, the "pulldown" attribute is deprecated, use "style" attribute instead.
public static final String ATT_PULLDOWN = "pulldown"; //$NON-NLS-1$
private PluginActionSet actionSet;
private IWorkbenchWindow window;
private ArrayList adjunctContributions = new ArrayList(0);
/**
* Constructs a new builder.
*/
public PluginActionSetBuilder() {
}
/* (non-Javadoc)
* Method declared on PluginActionBuilder.
*/
protected ActionDescriptor createActionDescriptor(IConfigurationElement element) {
// As of 2.1, the "pulldown" attribute was deprecated and replaced by
// the attribute "style". See doc for more details.
boolean pullDownStyle = false;
String style = element.getAttribute(ActionDescriptor.ATT_STYLE);
if (style != null) {
pullDownStyle = style.equals(ActionDescriptor.STYLE_PULLDOWN);
} else {
String pulldown = element.getAttribute(ATT_PULLDOWN);
pullDownStyle = pulldown != null && pulldown.equals("true"); //$NON-NLS-1$
}
ActionDescriptor desc = null;
if (pullDownStyle)
desc = new ActionDescriptor(element, ActionDescriptor.T_WORKBENCH_PULLDOWN, window);
else
desc = new ActionDescriptor(element, ActionDescriptor.T_WORKBENCH, window);
WWinPluginAction action = (WWinPluginAction) desc.getAction();
action.setActionSetId(actionSet.getDesc().getId());
actionSet.addPluginAction(action);
return desc;
}
/* (non-Javadoc)
* Method declared on PluginActionBuilder.
*/
protected BasicContribution createContribution() {
return new ActionSetContribution(actionSet.getDesc().getId(), window);
}
/**
* Returns the insertion point for a new contribution item. Clients should
* use this item as a reference point for insertAfter.
*
* @param startId the reference id for insertion
* @param sortId the sorting id for the insertion. If null then the item
* will be inserted at the end of all action sets.
* @param mgr the target menu manager.
* @param startVsEnd if <code>true</code> the items are added at the start of
* action with the same id; else they are added to the end
* @return the insertion point, or null if not found.
*/
public static IContributionItem findInsertionPoint(String startId, String sortId, IContributionManager mgr, boolean startVsEnd) {
// Get items.
IContributionItem[] items = mgr.getItems();
// Find the reference item.
int insertIndex = 0;
while (insertIndex < items.length) {
if (startId.equals(items[insertIndex].getId()))
break;
++insertIndex;
}
if (insertIndex >= items.length)
return null;
// Calculate startVsEnd comparison value.
int compareMetric = 0;
if (startVsEnd)
compareMetric = 1;
// Find the insertion point for the new item.
// We do this by iterating through all of the previous
// action set contributions define within the current group.
for (int nX = insertIndex + 1; nX < items.length; nX++) {
IContributionItem item = items[nX];
if (item.isSeparator() || item.isGroupMarker()) {
// Fix for bug report 18357
break;
}
if (item instanceof IActionSetContributionItem) {
if (sortId != null) {
String testId = ((IActionSetContributionItem) item).getActionSetId();
if (sortId.compareTo(testId) < compareMetric)
break;
}
insertIndex = nX;
} else {
break;
}
}
// Return item.
return items[insertIndex];
}
/**
*/
/* package */ static void processActionSets(ArrayList pluginActionSets, WorkbenchWindow window) {
// Process the action sets in two passes. On the first pass the pluginActionSetBuilder
// will process base contributions and cache adjunct contributions. On the second
// pass the adjunct contributions will be processed.
PluginActionSetBuilder[] builders = new PluginActionSetBuilder[pluginActionSets.size()];
for (int i =0; i<pluginActionSets.size(); i++) {
PluginActionSet set = (PluginActionSet)pluginActionSets.get(i);
PluginActionSetBuilder builder = new PluginActionSetBuilder();
builder.readActionExtensions(set, window);
builders[i] = builder;
}
for (int i =0; i<builders.length; i++) {
PluginActionSetBuilder builder = builders[i];
builder.processAdjunctContributions();
}
}
/**
*/
protected void processAdjunctContributions() {
// Contribute the adjunct contributions.
for (int i=0; i<adjunctContributions.size(); i++) {
ActionSetContribution contribution = (ActionSetContribution)adjunctContributions.get(i);
ActionSetActionBars bars = actionSet.getBars();
for (int j=0; j< contribution.adjunctActions.size(); j++) {
ActionDescriptor adjunctAction = (ActionDescriptor)contribution.adjunctActions.get(j);
contribution.contributeAdjunctCoolbarAction(adjunctAction, bars);
}
}
}
/**
* Read the actions within a config element.
*/
protected void readActionExtensions(PluginActionSet set, IWorkbenchWindow window) {
this.actionSet = set;
this.window = window;
cache = null;
currentContribution = null;
targetID = null;
targetContributionTag = TAG_ACTION_SET;
readElements(new IConfigurationElement[] {set.getConfigElement()});
if (cache != null) {
for (int i = 0; i < cache.size(); i++) {
ActionSetContribution contribution = (ActionSetContribution)cache.get(i);
contribution.contribute(actionSet.getBars(), true, true);
if (contribution.isAdjunctContributor()) {
adjunctContributions.add(contribution);
}
}
} else {
WorkbenchPlugin.log("Action Set is empty: " + set.getDesc().getId()); //$NON-NLS-1$
}
}
/**
* Helper class to collect the menus and actions defined within a
* contribution element.
*/
private static class ActionSetContribution extends BasicContribution {
private String actionSetId;
private WorkbenchWindow window;
private ArrayList adjunctActions = new ArrayList(0);
public ActionSetContribution(String id, IWorkbenchWindow window) {
super();
actionSetId = id;
this.window = (WorkbenchWindow)window;
}
/**
* This implementation inserts the group into the action set additions group.
*/
protected void addGroup(IContributionManager mgr, String name) {
IContributionItem refItem = findInsertionPoint(IWorkbenchActionConstants.MB_ADDITIONS, actionSetId, mgr, true);
// Insert the new group marker.
ActionSetSeparator group = new ActionSetSeparator(name, actionSetId);
if (refItem == null) {
mgr.add(group);
} else {
mgr.insertAfter(refItem.getId(), group);
}
}
/**
* Contributes submenus and/or actions into the provided menu and tool bar
* managers.
*/
public void contribute(IActionBars bars, boolean menuAppendIfMissing, boolean toolAppendIfMissing) {
IMenuManager menuMgr = bars.getMenuManager();
IToolBarManager toolBarMgr = bars.getToolBarManager();
if (menus != null && menuMgr != null) {
for (int i = 0; i < menus.size(); i++) {
IConfigurationElement menuElement = (IConfigurationElement) menus.get(i);
contributeMenu(menuElement, menuMgr, menuAppendIfMissing);
}
}
boolean isCoolBarContribution = (toolBarMgr != null) && (toolBarMgr instanceof CoolItemToolBarManager);
if (actions != null) {
for (int i = 0; i < actions.size(); i++) {
ActionDescriptor ad = (ActionDescriptor) actions.get(i);
if (menuMgr != null)
contributeMenuAction(ad, menuMgr, menuAppendIfMissing);
if (toolBarMgr != null) {
if (isCoolBarContribution) {
contributeCoolbarAction(ad, (ActionSetActionBars)bars);
} else {
contributeToolbarAction(ad, toolBarMgr, toolAppendIfMissing);
}
}
}
}
}
/**
* Contributes action from the action descriptor into the cool bar manager.
*/
protected void contributeAdjunctCoolbarAction(ActionDescriptor ad, ActionSetActionBars bars) {
String toolBarId = ad.getToolbarId();
String toolGroupId = ad.getToolbarGroupId();
String contributingId = bars.getActionSetId();
CoolBarManager coolBarMgr = ((CoolItemToolBarManager)bars.getToolBarManager()).getParentManager();
PluginAction action = ad.getAction();
PluginActionCoolBarContributionItem actionContribution = new PluginActionCoolBarContributionItem(action);
bars.addAdjunctContribution(actionContribution);
// create a coolitem for the toolbar id if it does not yet exist
CoolItemToolBarManager activeManager;
CoolBarContributionItem cbItem = (CoolBarContributionItem)coolBarMgr.find(toolBarId);
if (cbItem == null) {
cbItem = new CoolBarContributionItem(coolBarMgr, toolBarId);
cbItem.setVisible(true);
IContributionItem refItem = findCoolItemInsertionPoint(toolBarId, coolBarMgr);
if (refItem == null) {
coolBarMgr.add(cbItem);
} else {
coolBarMgr.insertAfter(refItem.getId(), cbItem);
}
}
activeManager = cbItem.getToolBarManager();
IContributionItem groupMarker = activeManager.find(toolGroupId);
if (groupMarker == null) {
activeManager.addAdjunctGroup(toolGroupId, contributingId);
}
activeManager.addAdjunctItemToGroup(toolGroupId, contributingId, actionContribution);
}
/**
* Contributes action from the action descriptor into the cool bar manager.
*/
protected void contributeCoolbarAction(ActionDescriptor ad, ActionSetActionBars bars) {
String toolBarId = ad.getToolbarId();
String toolGroupId = ad.getToolbarGroupId();
if (toolBarId == null && toolGroupId == null)return;
String contributingId = bars.getActionSetId();
CoolBarManager coolBarMgr = ((CoolItemToolBarManager)bars.getToolBarManager()).getParentManager();
if (toolBarId == null || toolBarId.equals("Normal") || toolBarId.equals("")) { //$NON-NLS-1$ //$NON-NLS-2$
// the item is being added to the coolitem for its action set
toolBarId = contributingId;
}
if (!toolBarId.equals(contributingId)) {
// adding to another action set, validate the id
if (!coolBarMgr.isValidCoolItemId(toolBarId, window)) {
// toolbarid not valid, add the item to the coolitem for its action set
toolBarId = contributingId;
} else {
adjunctActions.add(ad);
return;
}
}
PluginAction action = ad.getAction();
PluginActionCoolBarContributionItem actionContribution = new PluginActionCoolBarContributionItem(action);
// create a coolitem for the toolbar id if it does not yet exist
CoolItemToolBarManager activeManager;
CoolBarContributionItem cbItem = (CoolBarContributionItem)coolBarMgr.find(toolBarId);
if (cbItem == null) {
activeManager = (CoolItemToolBarManager)bars.getToolBarManager();
cbItem = activeManager.getCoolBarItem();
cbItem.setVisible(true);
IContributionItem refItem = findCoolItemInsertionPoint(toolBarId, coolBarMgr);
if (refItem == null) {
coolBarMgr.add(cbItem);
} else {
coolBarMgr.insertAfter(refItem.getId(), cbItem);
}
}
activeManager = cbItem.getToolBarManager();
IContributionItem groupMarker = activeManager.find(toolGroupId);
if (groupMarker == null) {
activeManager.addBaseGroup(toolGroupId, true);
}
activeManager.addBaseItemToGroup(toolGroupId, actionContribution);
}
/* (non-Javadoc)
* Method declared on Basic Contribution.
*/
protected void insertMenuGroup(IMenuManager menu, AbstractGroupMarker marker) {
if (actionSetId != null) {
IContributionItem[] items = menu.getItems();
// Loop thru all the current groups looking for the first
// group whose id > than the current action set id. Insert
// current marker just before this item then.
for (int i = 0; i < items.length; i++) {
IContributionItem item = items[i];
if (item.isSeparator() || item.isGroupMarker()) {
if (item instanceof IActionSetContributionItem) {
String testId = ((IActionSetContributionItem) item).getActionSetId();
if (actionSetId.compareTo(testId) < 0) {
menu.insertBefore(items[i].getId(), marker);
return;
}
}
}
}
}
menu.add(marker);
}
public IContributionItem findCoolItemInsertionPoint(String sortId, CoolBarManager mgr) {
// Get items.
IContributionItem[] items = mgr.getItems();
String startId = IWorkbenchActionConstants.MB_ADDITIONS;
// Find the reference item.
int insertIndex = 0;
// looking for the org.eclipse.ui.workbench.file toolbar
while (insertIndex < items.length) {
CoolBarContributionItem item = (CoolBarContributionItem) items[insertIndex];
IContributionItem foundItem = item.getToolBarManager().find(startId);
if (foundItem != null)
break;
++insertIndex;
}
if (insertIndex >= items.length)
return null;
// Find the insertion point for the new item. We do this by iterating
// through all of the previous action set contributions. This code
// assumes action set contributions are done in alphabetical order.
for (int i = insertIndex + 1; i < items.length; i++) {
CoolBarContributionItem item = (CoolBarContributionItem) items[i];
String testId = item.getId();
if (window != null) {
if (window.isWorkbenchCoolItemId(testId)) break;
}
// sort based only on existing action sets
if (sortId != null) {
if (sortId.compareTo(testId) < 1)
break;
}
insertIndex = i;
}
// Return item.
return items[insertIndex];
}
public boolean isAdjunctContributor() {
return adjunctActions.size() > 0;
}
/* (non-Javadoc)
* Method declared on Basic Contribution.
*/
protected void insertAfter(IContributionManager mgr, String refId, IContributionItem item) {
IContributionItem refItem = findInsertionPoint(refId, actionSetId, mgr, true);
if (refItem != null) {
mgr.insertAfter(refItem.getId(), item);
} else {
WorkbenchPlugin.log("Reference item " + refId + " not found for action " + item.getId()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
}