/******************************************************************************* * Copyright (c) 2006, 2015 Intel 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: * Intel Corporation - initial API and implementation * Warren Paul (Nokia) - bug 200420. *******************************************************************************/ package org.eclipse.cdt.ui.actions; import java.util.HashSet; import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.ui.cview.IncludeRefContainer; import org.eclipse.cdt.internal.ui.cview.IncludeReferenceProxy; /** * Base class for build configuration actions. */ public class ChangeBuildConfigActionBase { /** * List of selected managed-built projects */ protected HashSet<IProject> fProjects = new HashSet<IProject>(); /** * Fills the menu with build configurations which are common for all selected projects * @param menu The menu to fill */ protected void fillMenu(Menu menu) { // This should not happen if (menu == null) return; MenuItem[] items = menu.getItems(); for (MenuItem item2 : items) item2.dispose(); SortedSet<String> configNames = new TreeSet<String>(); String sCurrentConfig = null; boolean bCurrentConfig = true; for (IProject prj : fProjects) { ICConfigurationDescription[] cfgDescs = getCfgs(prj); String sActiveConfig = null; // Store names and detect active configuration for (ICConfigurationDescription cfgDesc : cfgDescs) { String s = cfgDesc.getName(); if (!configNames.contains(s)) configNames.add(s); if (cfgDesc.isActive()) sActiveConfig = s; } // Check whether all projects have the same active configuration if (bCurrentConfig) { if (sCurrentConfig == null) sCurrentConfig = sActiveConfig; else { if (!sCurrentConfig.equals(sActiveConfig)) bCurrentConfig = false; } } } int accel = 0; for (String sName : configNames) { String sDesc = null; boolean commonName = true; boolean commonDesc = true; boolean firstProj = true; for (IProject prj : fProjects) { ICConfigurationDescription[] cfgDescs = getCfgs(prj); int i = 0; for (; i < cfgDescs.length; i++) { if (cfgDescs[i].getName().equals(sName)) { String sNewDesc = cfgDescs[i].getDescription(); if (sNewDesc != null && sNewDesc.length() == 0) { sNewDesc = null; } if (commonDesc) { if (firstProj) { sDesc = sNewDesc; firstProj = false; } else if (sNewDesc == null && sDesc != null || sNewDesc != null && !sNewDesc.equals(sDesc)) { commonDesc = false; } } break; } } if (i == cfgDescs.length) { commonName = false; break; } } if (commonName) { StringBuffer builder = new StringBuffer(sName); if (commonDesc) { if (sDesc != null) { builder.append(" ("); //$NON-NLS-1$ builder.append(sDesc); builder.append(")"); //$NON-NLS-1$ } } else { builder.append(" (...)"); //$NON-NLS-1$ } IAction action = makeAction(sName ,builder, accel); if (bCurrentConfig && sCurrentConfig != null && sCurrentConfig.equals(sName)) { action.setChecked(true); } ActionContributionItem item = new ActionContributionItem(action); item.fill(menu, -1); accel++; } } } protected IAction makeAction(String sName, StringBuffer builder, int accel) { return new ChangeConfigAction(fProjects, sName, builder.toString(), accel + 1); } /** * Class used to efficiently special case the scenario where there's only a single project in the * workspace. See bug 375760 */ private static class ImaginarySelection implements ISelection { private IProject fProject; ImaginarySelection(IProject project) { fProject = project; } @Override public boolean isEmpty() { return fProject == null; } IProject getProject() { return fProject; } } /** * selectionChanged() event handler. Fills the list of managed-built projects * based on the selection. If some non-managed-built projects are selected, * disables the action. * @param action The action * @param selection The selection */ protected void onSelectionChanged(IAction action, ISelection selection) { fProjects.clear(); boolean badObject = false; if (selection != null ) { if (selection instanceof IStructuredSelection) { if (selection.isEmpty()) { // could be a form editor or something. try to get the project from the active part IWorkbenchPage page = CUIPlugin.getActivePage(); if (page != null) { IWorkbenchPart part = page.getActivePart(); if (part != null) { Object o = part.getAdapter(IResource.class); if (o != null && o instanceof IResource) { fProjects.add(((IResource)o).getProject()); } } } } Iterator<?> iter = ((IStructuredSelection)selection).iterator(); while (iter.hasNext()) { Object selItem = iter.next(); IProject project = null; if (selItem instanceof ICElement) { ICProject cproject = ((ICElement)selItem).getCProject(); if (cproject != null) project = cproject.getProject(); } else if (selItem instanceof IResource) { project = ((IResource)selItem).getProject(); } else if (selItem instanceof IncludeRefContainer) { ICProject fCProject = ((IncludeRefContainer)selItem).getCProject(); if (fCProject != null) project = fCProject.getProject(); } else if (selItem instanceof IncludeReferenceProxy) { IncludeRefContainer irc = ((IncludeReferenceProxy)selItem).getIncludeRefContainer(); if (irc != null) { ICProject fCProject = irc.getCProject(); if (fCProject != null) project = fCProject.getProject(); } } else if (selItem instanceof IAdaptable) { Object adapter = ((IAdaptable)selItem).getAdapter(IProject.class); if (adapter != null && adapter instanceof IProject) { project = (IProject)adapter; } } // Check whether the project is CDT project if (project != null) { if (!CoreModel.getDefault().isNewStyleProject(project)) project = null; else { ICConfigurationDescription[] tmp = getCfgs(project); if (tmp.length == 0) project = null; } } if (project != null) { fProjects.add(project); } else { badObject = true; break; } } } else if (selection instanceof ITextSelection) { // If a text selection check the selected part to see if we can find // an editor part that we can adapt to a resource and then // back to a project. IWorkbenchWindow window = CUIPlugin.getActiveWorkbenchWindow(); if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) { IWorkbenchPart part = page.getActivePart(); if (part instanceof IEditorPart) { IEditorPart epart = (IEditorPart) part; IResource resource = epart.getEditorInput().getAdapter(IResource.class); if (resource != null) { IProject project = resource.getProject(); badObject = !(project != null && CoreModel.getDefault().isNewStyleProject(project)); if (!badObject) { fProjects.add(project); } } } } } } else if (selection instanceof ImaginarySelection) { fProjects.add(((ImaginarySelection)selection).getProject()); } } boolean enable = false; if (!badObject && !fProjects.isEmpty()) { Iterator<IProject> iter = fProjects.iterator(); ICConfigurationDescription[] firstConfigs = getCfgs(iter.next()); if (firstConfigs!=null) { for (ICConfigurationDescription firstConfig : firstConfigs) { boolean common = true; Iterator<IProject> iter2 = fProjects.iterator(); while (iter2.hasNext()) { ICConfigurationDescription[] currentConfigs = getCfgs(iter2.next()); int j = 0; for (; j < currentConfigs.length; j++) { if (firstConfig.getName().equals(currentConfigs[j].getName())) break; } if (j == currentConfigs.length) { common = false; break; } } if (common) { enable = true; break; } } } } action.setEnabled(enable); // Bug 375760 // If focus is on a view that doesn't provide a resource/project context. Use the selection in a // project/resource view. We support three views. If more than one is open, nevermind. If there's only // one project in the workspace and it's a CDT one, use it unconditionally. // // Note that whatever project we get here is just a candidate; it's tested for suitability when we // call ourselves recursively // if (badObject || fProjects.isEmpty()) { // Check for lone CDT project in workspace IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); if (projects != null && projects.length == 1) { IProject project = projects[0]; if (CoreModel.getDefault().isNewStyleProject(project) && (getCfgs(project).length > 0)) { onSelectionChanged(action, new ImaginarySelection(project)); return; } } // Check the three supported views IWorkbenchPage page = CUIPlugin.getActivePage(); int viewCount = 0; if (page != null) { IViewReference theViewRef = null; IViewReference viewRef = null; theViewRef = page.findViewReference("org.eclipse.cdt.ui.CView"); //$NON-NLS-1$ viewCount += (theViewRef != null) ? 1 : 0; viewRef = page.findViewReference("org.eclipse.ui.navigator.ProjectExplorer"); //$NON-NLS-1$ viewCount += (viewRef != null) ? 1 : 0; theViewRef = (theViewRef == null) ? viewRef : theViewRef; viewRef = page.findViewReference("org.eclipse.ui.views.ResourceNavigator"); //$NON-NLS-1$ viewCount += (viewRef != null) ? 1 : 0; theViewRef = (theViewRef == null) ? viewRef : theViewRef; if (theViewRef != null && viewCount == 1) { IViewPart view = theViewRef.getView(false); if (view != null) { ISelection cdtSelection = view.getSite().getSelectionProvider().getSelection(); if (cdtSelection != null) { if (!cdtSelection.isEmpty()) { if (!cdtSelection.equals(selection)) { // avoids infinite recursion onSelectionChanged(action, cdtSelection); } } } } } } } } private ICConfigurationDescription[] getCfgs(IProject prj) { ICProjectDescription prjd = CoreModel.getDefault().getProjectDescription(prj, false); if (prjd != null) { ICConfigurationDescription[] cfgs = prjd.getConfigurations(); if (cfgs != null) { return cfgs; } } return new ICConfigurationDescription[0]; } }