| /******************************************************************************* |
| * Copyright (c) 2008, 2016 Wind River Systems, Inc. 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: |
| * Wind River Systems - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.tcf.internal.cdt.ui; |
| |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| |
| import org.eclipse.cdt.core.CCorePlugin; |
| import org.eclipse.cdt.core.model.CModelException; |
| import org.eclipse.cdt.core.model.CoreModel; |
| import org.eclipse.cdt.core.model.IBinary; |
| 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.launch.LaunchUtils; |
| import org.eclipse.cdt.ui.CElementLabelProvider; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.debug.ui.ILaunchConfigurationDialog; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.custom.BusyIndicator; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.tcf.debug.ui.ITCFLaunchContext; |
| import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.dialogs.TwoPaneElementSelector; |
| |
| public class TCFLaunchContext implements ITCFLaunchContext { |
| |
| public boolean isSupportedSelection(Object selection) { |
| if (selection == null) { |
| return getContext(null) != null; |
| } |
| if (selection instanceof IProject) { |
| return CoreModel.getDefault().getCModel().getCProject(((IProject)selection).getName()) != null; |
| } |
| return selection instanceof ICElement; |
| } |
| |
| public IPath getPath(Object selection) { |
| if (selection instanceof IResource) { |
| return ((IResource)selection).getLocation(); |
| } |
| if (selection instanceof ICElement) { |
| IResource res = ((ICElement)selection).getResource(); |
| if (res != null) return res.getLocation(); |
| } |
| return null; |
| } |
| |
| public IProject getProject(Object selection) { |
| if (selection instanceof IProject) return (IProject)selection; |
| if (selection instanceof ICElement) return ((ICElement)selection).getCProject().getProject(); |
| return null; |
| } |
| |
| public void setDefaults(ILaunchConfigurationDialog dlg, ILaunchConfigurationWorkingCopy config) { |
| ICElement element = getContext(config); |
| if (element != null) { |
| initializeCProject(element, config); |
| initializeProgramName(element, dlg, config); |
| } |
| } |
| |
| /** |
| * Returns the current C element context from which to initialize default |
| * settings, or <code>null</code> if none. Note, if possible we will |
| * return the IBinary based on configuration entry as this may be more useful then |
| * just the project. |
| * |
| * @return C element context. |
| */ |
| private ICElement getContext(ILaunchConfiguration config) { |
| String projectName = null; |
| String programName = null; |
| if (config != null) { |
| try { |
| projectName = config.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, (String)null); |
| programName = config.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, (String)null); |
| } |
| catch (CoreException e) { |
| Activator.log(e); |
| } |
| } |
| Object obj = null; |
| IWorkbenchPage page = Activator.getActivePage(); |
| if (projectName != null && !projectName.equals("")) { //$NON-NLS-1$ |
| IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); |
| ICProject cProject = CCorePlugin.getDefault().getCoreModel().create(project); |
| if (cProject != null && cProject.exists()) obj = cProject; |
| } |
| else { |
| if (page != null) { |
| ISelection selection = page.getSelection(); |
| if (selection instanceof IStructuredSelection) { |
| IStructuredSelection ss = (IStructuredSelection)selection; |
| if (!ss.isEmpty()) obj = ss.getFirstElement(); |
| } |
| } |
| } |
| if (obj instanceof IResource) { |
| ICElement ce = CoreModel.getDefault().create((IResource)obj); |
| if (ce == null) { |
| IProject pro = ((IResource)obj).getProject(); |
| ce = CoreModel.getDefault().create(pro); |
| } |
| obj = ce; |
| } |
| if (obj instanceof ICElement) { |
| if (programName == null || programName.equals("")) { //$NON-NLS-1$ |
| return (ICElement)obj; |
| } |
| ICElement ce = (ICElement)obj; |
| IProject project; |
| project = (IProject)ce.getCProject().getResource(); |
| IPath programFile = project.getFile(programName).getLocation(); |
| ce = CCorePlugin.getDefault().getCoreModel().create(programFile); |
| if (ce != null && ce.exists()) return ce; |
| return (ICElement)obj; |
| } |
| if (page != null) { |
| IEditorPart part = page.getActiveEditor(); |
| |
| if (part != null) { |
| IEditorInput input = part.getEditorInput(); |
| return (ICElement)input.getAdapter(ICElement.class); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Set the C project attribute based on the ICElement. |
| */ |
| private void initializeCProject(ICElement cElement, ILaunchConfigurationWorkingCopy config) { |
| ICProject cProject = cElement.getCProject(); |
| String name = null; |
| if (cProject != null && cProject.exists()) { |
| name = cProject.getElementName(); |
| config.setMappedResources(new IResource[] {cProject.getProject()}); |
| } |
| config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, name); |
| } |
| |
| /** |
| * Set the program name attributes on the working copy based on the ICElement |
| */ |
| private void initializeProgramName(ICElement cElement, ILaunchConfigurationDialog dlg, ILaunchConfigurationWorkingCopy config) { |
| |
| boolean renamed = false; |
| |
| if (!(cElement instanceof IBinary)) { |
| cElement = cElement.getCProject(); |
| } |
| |
| if (cElement instanceof ICProject) { |
| |
| IProject project = cElement.getCProject().getProject(); |
| String name = project.getName(); |
| ICProjectDescription projDes = CCorePlugin.getDefault().getProjectDescription(project); |
| if (projDes != null) { |
| String buildConfigName = projDes.getActiveConfiguration().getName(); |
| name = name + " " + buildConfigName; //$NON-NLS-1$ |
| } |
| name = dlg.generateName(name); |
| config.rename(name); |
| renamed = true; |
| } |
| |
| IBinary binary = null; |
| if (cElement instanceof ICProject) { |
| IBinary[] bins = getBinaryFiles((ICProject)cElement); |
| if (bins != null && bins.length == 1) { |
| binary = bins[0]; |
| } |
| } |
| else if (cElement instanceof IBinary) { |
| binary = (IBinary)cElement; |
| } |
| |
| if (binary != null) { |
| String path; |
| path = binary.getResource().getProjectRelativePath().toOSString(); |
| config.setAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, path); |
| if (!renamed) |
| { |
| String name = binary.getElementName(); |
| int index = name.lastIndexOf('.'); |
| if (index > 0) { |
| name = name.substring(0, index); |
| } |
| name = dlg.generateName(name); |
| config.rename(name); |
| renamed = true; |
| } |
| } |
| |
| if (!renamed) { |
| String name = dlg.generateName(cElement.getCProject().getElementName()); |
| config.rename(name); |
| } |
| } |
| |
| public String getBuildConfigID(IProject project) { |
| ICProjectDescription projDes = CCorePlugin.getDefault().getProjectDescription(project); |
| if (projDes == null) return null; |
| return projDes.getActiveConfiguration().getId(); |
| } |
| |
| public Map<String,String> getBuildConfigIDs(IProject project) { |
| ICProjectDescription projDes = CCorePlugin.getDefault().getProjectDescription(project); |
| if (projDes == null) return null; |
| ICConfigurationDescription[] configurations = projDes.getConfigurations(); |
| if (configurations == null) return null; |
| Map<String,String> map = new LinkedHashMap<String,String>(); |
| for (ICConfigurationDescription c : configurations) map.put(c.getId(), c.getName()); |
| return map; |
| } |
| |
| /** |
| * Iterate through and suck up all of the executable files that we can find. |
| */ |
| private IBinary[] getBinaryFiles(final ICProject cproject) { |
| if (cproject == null || !cproject.exists()) return null; |
| final Display display = Display.getCurrent(); |
| final Object[] ret = new Object[1]; |
| BusyIndicator.showWhile(display, new Runnable() { |
| |
| public void run() { |
| try { |
| ret[0] = cproject.getBinaryContainer().getBinaries(); |
| } |
| catch (CModelException e) { |
| Activator.errorDialog("Launch UI internal error", e); |
| } |
| } |
| }); |
| return (IBinary[])ret[0]; |
| } |
| |
| /** |
| * Return true if given file path names a binary file. |
| * @param project |
| * @param path |
| * @return true if binary file. |
| * @throws CoreException |
| */ |
| public boolean isBinary(IProject project, IPath path) throws CoreException { |
| return LaunchUtils.getBinary(project, path) != null; |
| } |
| |
| public String chooseBinary(Shell shell, IProject project) { |
| ILabelProvider programLabelProvider = new CElementLabelProvider() { |
| |
| @Override |
| public String getText(Object element) { |
| if (element instanceof IBinary) { |
| IBinary bin = (IBinary)element; |
| StringBuffer name = new StringBuffer(); |
| name.append(bin.getPath().lastSegment()); |
| return name.toString(); |
| } |
| return super.getText(element); |
| } |
| |
| @Override |
| public Image getImage(Object element) { |
| if (! (element instanceof ICElement)) { |
| return super.getImage(element); |
| } |
| ICElement celement = (ICElement)element; |
| |
| if (celement.getElementType() == ICElement.C_BINARY) { |
| IBinary belement = (IBinary)celement; |
| if (belement.isExecutable()) { |
| return DebugUITools.getImage(IDebugUIConstants.IMG_ACT_RUN); |
| } |
| } |
| |
| return super.getImage(element); |
| } |
| }; |
| |
| ILabelProvider qualifierLabelProvider = new CElementLabelProvider() { |
| |
| @Override |
| public String getText(Object element) { |
| if (element instanceof IBinary) { |
| IBinary bin = (IBinary)element; |
| StringBuffer name = new StringBuffer(); |
| name.append(bin.getCPU() + (bin.isLittleEndian() ? "le" : "be")); //$NON-NLS-1$ //$NON-NLS-2$ |
| name.append(" - "); //$NON-NLS-1$ |
| name.append(bin.getPath().toString()); |
| return name.toString(); |
| } |
| return super.getText(element); |
| } |
| }; |
| |
| TwoPaneElementSelector dialog = new TwoPaneElementSelector(shell, programLabelProvider, qualifierLabelProvider); |
| dialog.setElements(getBinaryFiles(getCProject(project.getName()))); |
| dialog.setMessage("Choose program to run"); |
| dialog.setTitle("Program Selection"); |
| dialog.setUpperListLabel("Binaries:"); |
| dialog.setLowerListLabel("Qualifier:"); |
| dialog.setMultipleSelection(false); |
| // dialog.set |
| if (dialog.open() != Window.OK) return null; |
| IBinary binary = (IBinary)dialog.getFirstResult(); |
| return binary.getResource().getProjectRelativePath().toString(); |
| } |
| |
| /** |
| * Return the ICProject corresponding to the project name in the project name text field, or |
| * null if the text does not match a project name. |
| */ |
| private ICProject getCProject(String name) { |
| String projectName = name.trim(); |
| if (projectName.length() < 1) return null; |
| return CoreModel.getDefault().getCModel().getCProject(projectName); |
| } |
| } |