blob: 4a66ec42e604e1d67c624db0b577e8ce9487a99f [file] [log] [blame]
/*******************************************************************************
* 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);
}
}