/******************************************************************************* * Copyright (c) 2000, 2009 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 * Anton Leherbauer (Wind River Systems) - adaptations for Common Navigator *******************************************************************************/ package org.eclipse.cdt.internal.ui.navigator; import java.util.Iterator; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IViewPart; import org.eclipse.ui.actions.BuildAction; import org.eclipse.ui.ide.IDEActionFactory; import org.eclipse.ui.navigator.ICommonMenuConstants; import org.eclipse.cdt.internal.ui.cview.BuildGroup; import org.eclipse.cdt.internal.ui.cview.CViewMessages; /** * Common Navigator compatible clone of {@link org.eclipse.cdt.internal.ui.cview.BuildGroup}. * <p> * Adds action "Clean Project" and group marker "buildGroup" to the context menu. * </p> * @see org.eclipse.cdt.internal.ui.cview.BuildGroup * @see org.eclipse.ui.actions.BuildAction */ public class CNavigatorBuildActionGroup extends AbstractCNavigatorActionGroup { private BuildAction fBuildAction; private BuildAction fCleanAction; // Menu tags for the build final String BUILD_GROUP_MARKER= "buildGroup"; //$NON-NLS-1$ final String BUILD_GROUP_MARKER_END= "end-buildGroup"; //$NON-NLS-1$ /** * Create action group associated with given view part. * @param viewPart */ public CNavigatorBuildActionGroup(IViewPart viewPart) { super(viewPart); } @Override public void fillActionBars(IActionBars actionBars) { // register a CDT Build project action which prevents projects with refs from being built twice actionBars.setGlobalActionHandler(IDEActionFactory.BUILD_PROJECT.getId(), fBuildAction); updateActionBars(); } /** * Adds the build actions to the context menu. * <p> * The following conditions apply: build-only projects selected, auto build * disabled, at least one * builder present * </p> * <p> * No disabled action should be on the context menu. * </p> * * @param menu * context menu to add actions to */ @Override public void fillContextMenu(IMenuManager menu) { IStructuredSelection selection= (IStructuredSelection) getContext().getSelection(); boolean isProjectSelection= true; boolean hasOpenProjects= false; boolean hasClosedProjects= false; boolean hasBuilder= true; // false if any project is closed or does // not have builder Iterator<?> resources= selection.iterator(); while (resources.hasNext() && (!hasOpenProjects || !hasClosedProjects || hasBuilder || isProjectSelection)) { Object next= resources.next(); IProject project= null; if (next instanceof IProject) { project= (IProject) next; } else if (next instanceof IAdaptable) { IResource res= (IResource)((IAdaptable)next).getAdapter(IResource.class); if (res instanceof IProject) { project= (IProject) res; } } if (project == null) { isProjectSelection= false; continue; } if (project.isOpen()) { hasOpenProjects= true; if (hasBuilder && !hasBuilder(project)) { hasBuilder= false; } } else { hasClosedProjects= true; hasBuilder= false; } } if (!selection.isEmpty() && isProjectSelection && hasBuilder) { fCleanAction.selectionChanged(selection); if (fCleanAction.isEnabled()) { IContributionItem oldBuild = menu.find(BuildAction.ID_BUILD); if (oldBuild != null) { menu.insertAfter(BuildAction.ID_BUILD, fCleanAction); // Replace ResourceMgmtActionProvier's build action with our own if (oldBuild instanceof ActionContributionItem && ((ActionContributionItem)oldBuild).getAction() instanceof BuildAction) { menu.remove(oldBuild); menu.insertBefore(fCleanAction.getId(), fBuildAction); } } else { menu.insertAfter(ICommonMenuConstants.GROUP_BUILD, fCleanAction); menu.insertAfter(ICommonMenuConstants.GROUP_BUILD, fBuildAction); } } } menu.appendToGroup(ICommonMenuConstants.GROUP_BUILD, new Separator(BUILD_GROUP_MARKER)); menu.appendToGroup(BUILD_GROUP_MARKER, new GroupMarker(BUILD_GROUP_MARKER_END)); } /** * Returns whether there are builders configured on the given project. * * @return <code>true</code> if it has builders, <code>false</code> if * not, or if this could not be determined */ boolean hasBuilder(IProject project) { try { ICommand[] commands= project.getDescription().getBuildSpec(); if (commands.length > 0) return true; } catch (CoreException e) { // Cannot determine if project has builders. Project is closed // or does not exist. Fall through to return false. } return false; } @Override protected void makeActions() { fBuildAction = new BuildGroup.CDTBuildAction(getViewPart().getSite(), IncrementalProjectBuilder.INCREMENTAL_BUILD); fCleanAction= new BuildGroup.CDTBuildAction(getViewPart().getSite(), IncrementalProjectBuilder.CLEAN_BUILD); fCleanAction.setText(CViewMessages.CleanAction_label); } @Override public void updateActionBars() { IStructuredSelection selection = (IStructuredSelection) getContext().getSelection(); fBuildAction.selectionChanged(selection); fCleanAction.selectionChanged(selection); } }