| /******************************************************************************* |
| * 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.List; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| |
| import org.eclipse.core.expressions.EvaluationContext; |
| import org.eclipse.core.expressions.EvaluationResult; |
| import org.eclipse.core.expressions.Expression; |
| import org.eclipse.core.expressions.ExpressionConverter; |
| import org.eclipse.core.expressions.IEvaluationContext; |
| |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.SelectionEnabler; |
| import org.eclipse.ui.model.IWorkbenchAdapter; |
| |
| /** |
| * This class describes the object contribution element within the popup menu |
| * action registry. |
| */ |
| public class ObjectActionContributor extends PluginActionBuilder implements IObjectActionContributor { |
| private static final String ATT_NAME_FILTER = "nameFilter"; //$NON-NLS-1$ |
| private static final String ATT_ADAPTABLE = "adaptable"; //$NON-NLS-1$ |
| private static final String P_TRUE = "true"; //$NON-NLS-1$ |
| private static final String TAG_ENABLEMENT= "enablement"; //$NON-NLS-1$ |
| |
| private IConfigurationElement config; |
| private boolean configRead = false; |
| private boolean adaptable = false; |
| |
| /** |
| * The constructor. |
| */ |
| public ObjectActionContributor(IConfigurationElement config) { |
| this.config = config; |
| this.adaptable = P_TRUE.equalsIgnoreCase(config.getAttribute(ATT_ADAPTABLE)); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IObjectContributor. |
| */ |
| public boolean canAdapt() { |
| return adaptable; |
| } |
| |
| |
| /* (non-Javadoc) |
| * Method declared on IObjectActionContributor. |
| */ |
| public void contributeObjectActionIdOverrides(List actionIdOverrides) { |
| if (!configRead) |
| readConfigElement(); |
| |
| // Easy case out if no actions |
| if (currentContribution.actions != null) { |
| for (int i = 0; i < currentContribution.actions.size(); i++) { |
| ActionDescriptor ad = (ActionDescriptor)currentContribution.actions.get(i); |
| String id = ad.getAction().getOverrideActionId(); |
| if (id != null) |
| actionIdOverrides.add(id); |
| } |
| } |
| } |
| |
| /** |
| * Contributes actions applicable for the current selection. |
| */ |
| public boolean contributeObjectActions(IWorkbenchPart part, IMenuManager menu, ISelectionProvider selProv, List actionIdOverrides) { |
| if (!configRead) |
| readConfigElement(); |
| |
| // Easy case out if no actions |
| if (currentContribution.actions == null) |
| return false; |
| |
| // Get a structured selection. |
| ISelection sel = selProv.getSelection(); |
| if ((sel == null) || !(sel instanceof IStructuredSelection)) |
| return false; |
| IStructuredSelection selection = (IStructuredSelection) sel; |
| |
| // Generate menu. |
| for (int i = 0; i < currentContribution.actions.size(); i++) { |
| ActionDescriptor ad = (ActionDescriptor)currentContribution.actions.get(i); |
| if (!actionIdOverrides.contains(ad.getId())) { |
| currentContribution.contributeMenuAction(ad, menu, true); |
| // Update action for the current selection and part. |
| if (ad.getAction() instanceof ObjectPluginAction) { |
| ObjectPluginAction action = (ObjectPluginAction) ad.getAction(); |
| action.setActivePart(part); |
| action.selectionChanged(selection); |
| } |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Contributes menus applicable for the current selection. |
| */ |
| public boolean contributeObjectMenus(IMenuManager menu, ISelectionProvider selProv) { |
| if (!configRead) |
| readConfigElement(); |
| |
| // Easy case out if no menus |
| if (currentContribution.menus == null) |
| return false; |
| |
| // Get a structured selection. |
| ISelection sel = selProv.getSelection(); |
| if ((sel == null) || !(sel instanceof IStructuredSelection)) |
| return false; |
| |
| // Generate menu. |
| for (int i = 0; i < currentContribution.menus.size(); i++) { |
| IConfigurationElement menuElement = (IConfigurationElement)currentContribution.menus.get(i); |
| currentContribution.contributeMenu(menuElement, menu, true); |
| } |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on PluginActionBuilder. |
| */ |
| protected ActionDescriptor createActionDescriptor(IConfigurationElement element) { |
| return new ActionDescriptor(element, ActionDescriptor.T_POPUP); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on PluginActionBuilder. |
| */ |
| protected BasicContribution createContribution() { |
| return new ObjectContribution(); |
| } |
| |
| /** |
| * Returns true if name filter is not specified for the contribution |
| * or the current selection matches the filter. |
| */ |
| public boolean isApplicableTo(Object object) { |
| if (!configRead) |
| readConfigElement(); |
| |
| if (!testName(object)) |
| return false; |
| |
| return ((ObjectContribution)currentContribution).isApplicableTo(object); |
| } |
| |
| /** |
| * Reads the configuration element and all the children. |
| * This creates an action descriptor for every action in the extension. |
| */ |
| private void readConfigElement() { |
| currentContribution = createContribution(); |
| readElementChildren(config); |
| configRead = true; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on PluginActionBuilder. |
| */ |
| protected boolean readElement(IConfigurationElement element) { |
| String tag = element.getName(); |
| |
| // Found visibility sub-element |
| if (tag.equals(PluginActionBuilder.TAG_VISIBILITY)) { |
| ((ObjectContribution)currentContribution).setVisibilityTest(element); |
| return true; |
| } |
| |
| // Found filter sub-element |
| if (tag.equals(PluginActionBuilder.TAG_FILTER)) { |
| ((ObjectContribution)currentContribution).addFilterTest(element); |
| return true; |
| } |
| |
| if (tag.equals(TAG_ENABLEMENT)) { |
| ((ObjectContribution)currentContribution).setEnablementTest(element); |
| return true; |
| } |
| |
| return super.readElement(element); |
| } |
| |
| /** |
| * Returns whether the current selection matches the contribution name filter. |
| */ |
| private boolean testName(Object object) { |
| String nameFilter = config.getAttribute(ATT_NAME_FILTER); |
| if (nameFilter == null) |
| return true; |
| String objectName = null; |
| if (object instanceof IAdaptable) { |
| IAdaptable element = (IAdaptable) object; |
| IWorkbenchAdapter de = (IWorkbenchAdapter) element.getAdapter(IWorkbenchAdapter.class); |
| if (de != null) |
| objectName = de.getLabel(element); |
| } |
| if (objectName == null) { |
| objectName = object.toString(); |
| } |
| return SelectionEnabler.verifyNameMatch(objectName, nameFilter); |
| } |
| |
| |
| /** |
| * Helper class to collect the menus and actions defined within a |
| * contribution element. |
| */ |
| private static class ObjectContribution extends BasicContribution { |
| private ObjectFilterTest filterTest; |
| private ActionExpression visibilityTest; |
| private Expression enablement; |
| |
| public void addFilterTest(IConfigurationElement element) { |
| if (filterTest == null) |
| filterTest = new ObjectFilterTest(); |
| filterTest.addFilterElement(element); |
| } |
| |
| public void setVisibilityTest(IConfigurationElement element) { |
| visibilityTest = new ActionExpression(element); |
| } |
| |
| public void setEnablementTest(IConfigurationElement element) { |
| try { |
| enablement= ExpressionConverter.getDefault().perform(element); |
| } catch (CoreException e) { |
| WorkbenchPlugin.getDefault().getLog().log(e.getStatus()); |
| } |
| } |
| |
| /** |
| * Returns true if name filter is not specified for the contribution |
| * or the current selection matches the filter. |
| */ |
| public boolean isApplicableTo(Object object) { |
| boolean result= true; |
| if (visibilityTest != null) { |
| result= result && visibilityTest.isEnabledFor(object); |
| if (!result) |
| return result; |
| } else if (filterTest != null) { |
| result= result && filterTest.matches(object, true); |
| if (!result) |
| return result; |
| } |
| if (enablement != null) { |
| try { |
| IEvaluationContext context= new EvaluationContext(null, object); |
| context.addVariable("selection", object); //$NON-NLS-1$ |
| EvaluationResult evalResult= enablement.evaluate(context); |
| if (evalResult == EvaluationResult.FALSE) |
| return false; |
| } catch (CoreException e) { |
| enablement= null; |
| WorkbenchPlugin.getDefault().getLog().log(e.getStatus()); |
| result= false; |
| } |
| } |
| return result; |
| } |
| } |
| } |