Bug 182388, Executables view and supporting classes.
|
@ -54,7 +54,7 @@ Export-Package: org.eclipse.cdt.core,
|
|||
org.eclipse.cdt.internal.core.index;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.index.provider;x-internal:=true,
|
||||
org.eclipse.cdt.internal.core.language;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core,org.eclipse.cdt.debug.ui",
|
||||
org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.core.parser;x-internal:=true,
|
||||
org.eclipse.cdt.internal.core.parser.problem;x-internal:=true,
|
||||
|
|
|
@ -44,7 +44,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
|
|||
org.eclipse.cdt.internal.ui.text.template;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.text.util;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.typehierarchy;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.util;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.util;x-friends:="org.eclipse.cdt.debug.ui",
|
||||
org.eclipse.cdt.internal.ui.viewsupport;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.wizards;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.wizards.classwizard;x-internal:=true,
|
||||
|
|
|
@ -12,6 +12,7 @@ Export-Package: org.eclipse.cdt.debug.core,
|
|||
org.eclipse.cdt.debug.core.cdi.event,
|
||||
org.eclipse.cdt.debug.core.cdi.model,
|
||||
org.eclipse.cdt.debug.core.cdi.model.type,
|
||||
org.eclipse.cdt.debug.core.executables,
|
||||
org.eclipse.cdt.debug.core.model,
|
||||
org.eclipse.cdt.debug.core.sourcelookup,
|
||||
org.eclipse.cdt.debug.internal.core,
|
||||
|
@ -21,6 +22,7 @@ Export-Package: org.eclipse.cdt.debug.core,
|
|||
Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
|
||||
org.eclipse.debug.core;bundle-version="[3.2.0,4.0.0)",
|
||||
org.eclipse.cdt.core;bundle-version="[5.0.0,6.0.0)",
|
||||
org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)"
|
||||
org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
|
||||
org.eclipse.core.filesystem;bundle-version="1.2.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.cdt.core.ISymbolReader;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.internal.core.model.BinaryParserConfig;
|
||||
import org.eclipse.cdt.internal.core.model.CModelManager;
|
||||
import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit;
|
||||
import org.eclipse.cdt.internal.core.model.TranslationUnit;
|
||||
import org.eclipse.core.filesystem.URIUtil;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
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.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
import org.eclipse.core.runtime.content.IContentType;
|
||||
import org.eclipse.core.runtime.content.IContentTypeManager;
|
||||
|
||||
public class Executable extends PlatformObject {
|
||||
|
||||
private IPath path;
|
||||
private IProject project;
|
||||
private String name;
|
||||
private IResource resource;
|
||||
private Map<ITranslationUnit, String> remappedPaths;
|
||||
private ArrayList<ITranslationUnit> sourceFiles;
|
||||
|
||||
public IPath getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public IProject getProject() {
|
||||
return project;
|
||||
}
|
||||
|
||||
public Executable(IPath path, IProject project, IResource resource) {
|
||||
this.path = path;
|
||||
this.project = project;
|
||||
this.name = new File(path.toOSString()).getName();
|
||||
this.resource = resource;
|
||||
remappedPaths = new HashMap<ITranslationUnit, String>();
|
||||
sourceFiles = new ArrayList<ITranslationUnit>();
|
||||
}
|
||||
|
||||
public IResource getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (adapter.equals(IResource.class))
|
||||
if (getResource() != null)
|
||||
return getResource();
|
||||
else
|
||||
return this.getProject();
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
|
||||
static public boolean isExecutableFile(IPath path) {
|
||||
// ignore directories
|
||||
if (path.toFile().isDirectory()) {
|
||||
return false;
|
||||
}
|
||||
// Only if file has no extension, has an extension that is an integer
|
||||
// or is a binary file content type
|
||||
String ext = path.getFileExtension();
|
||||
if (ext != null) {
|
||||
// shared libraries often have a version number
|
||||
boolean isNumber = true;
|
||||
for (int i = 0; i < ext.length(); ++i)
|
||||
if (!Character.isDigit(ext.charAt(i))) {
|
||||
isNumber = false;
|
||||
break;
|
||||
}
|
||||
if (!isNumber) {
|
||||
boolean isBinary = false;
|
||||
final IContentTypeManager ctm = Platform.getContentTypeManager();
|
||||
final IContentType ctbin = ctm.getContentType(CCorePlugin.CONTENT_TYPE_BINARYFILE);
|
||||
final IContentType[] cts = ctm.findContentTypesFor(path.toFile().getName());
|
||||
for (int i = 0; !isBinary && i < cts.length; i++) {
|
||||
isBinary = cts[i].isKindOf(ctbin);
|
||||
}
|
||||
if (!isBinary) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public IBinaryFile createBinaryFile() {
|
||||
CModelManager factory = CModelManager.getDefault();
|
||||
|
||||
if (resource != null && resource instanceof IFile)
|
||||
return factory.createBinaryFile((IFile) resource);
|
||||
|
||||
BinaryParserConfig[] parsers = factory.getBinaryParser(getProject());
|
||||
if (parsers.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isExecutableFile(path))
|
||||
return null;
|
||||
|
||||
File f = new File(path.toOSString());
|
||||
if (f.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int hints = 0;
|
||||
|
||||
for (int i = 0; i < parsers.length; i++) {
|
||||
IBinaryParser parser = null;
|
||||
try {
|
||||
parser = parsers[i].getBinaryParser();
|
||||
if (parser.getHintBufferSize() > hints) {
|
||||
hints = parser.getHintBufferSize();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
}
|
||||
byte[] bytes = new byte[hints];
|
||||
if (hints > 0) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(path.toFile());
|
||||
int count = 0;
|
||||
// Make sure we read up to 'hints' bytes if we possibly can
|
||||
while (count < hints) {
|
||||
int bytesRead = is.read(bytes, count, hints - count);
|
||||
if (bytesRead < 0)
|
||||
break;
|
||||
count += bytesRead;
|
||||
}
|
||||
if (count > 0 && count < bytes.length) {
|
||||
byte[] array = new byte[count];
|
||||
System.arraycopy(bytes, 0, array, 0, count);
|
||||
bytes = array;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < parsers.length; i++) {
|
||||
try {
|
||||
IBinaryParser parser = parsers[i].getBinaryParser();
|
||||
if (parser.isBinary(bytes, path)) {
|
||||
IBinaryFile binFile = parser.getBinary(bytes, path);
|
||||
if (binFile != null) {
|
||||
return binFile;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ITranslationUnit[] getSourceFiles() {
|
||||
// Try to get the list of source files used to build the binary from the
|
||||
// symbol information.
|
||||
|
||||
remappedPaths.clear();
|
||||
|
||||
sourceFiles.clear();
|
||||
|
||||
CModelManager factory = CModelManager.getDefault();
|
||||
IBinaryFile bin = createBinaryFile();
|
||||
|
||||
if (bin != null) {
|
||||
ICProject cproject = factory.create(project);
|
||||
|
||||
ISymbolReader symbolreader = (ISymbolReader) bin.getAdapter(ISymbolReader.class);
|
||||
if (symbolreader != null) {
|
||||
String[] symReaderSources = symbolreader.getSourceFiles();
|
||||
if (symReaderSources != null && symReaderSources.length > 0) {
|
||||
for (int i = 0; i < symReaderSources.length; i++) {
|
||||
String filename = symReaderSources[i];
|
||||
String orgPath = filename;
|
||||
|
||||
filename = ExecutablesManager.getExecutablesManager().remapSourceFile(filename);
|
||||
|
||||
// Sometimes the path in the symbolics will have a
|
||||
// different
|
||||
// case than the actual file system path. Even if the
|
||||
// file
|
||||
// system is not case sensitive this will confuse the
|
||||
// Path
|
||||
// class.
|
||||
// So make sure the path is canonical, otherwise
|
||||
// breakpoints
|
||||
// won't be resolved, etc..
|
||||
// Also check for relative path names and attempt to
|
||||
// resolve
|
||||
// them relative to the executable.
|
||||
|
||||
try {
|
||||
File file = new File(filename);
|
||||
if (file.exists()) {
|
||||
filename = file.getCanonicalPath();
|
||||
} else if (filename.startsWith(".")) { //$NON-NLS-1$
|
||||
file = new File(bin.getPath().removeLastSegments(1).toOSString(), filename);
|
||||
filename = file.getCanonicalPath();
|
||||
}
|
||||
} catch (IOException e) { // Do nothing.
|
||||
}
|
||||
|
||||
// See if this source file is already in the project.
|
||||
// We check this to determine if we should create a
|
||||
// TranslationUnit or ExternalTranslationUnit
|
||||
IFile sourceFile = getProject().getFile(filename);
|
||||
IPath path = new Path(filename);
|
||||
|
||||
IFile wkspFile = null;
|
||||
if (sourceFile.exists())
|
||||
wkspFile = sourceFile;
|
||||
else {
|
||||
IFile[] filesInWP = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path);
|
||||
|
||||
for (int j = 0; j < filesInWP.length; j++) {
|
||||
if (filesInWP[j].isAccessible()) {
|
||||
wkspFile = filesInWP[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a translation unit for this file and add it as
|
||||
// a child of the binary
|
||||
String id = CoreModel.getRegistedContentTypeId(sourceFile.getProject(), sourceFile.getName());
|
||||
|
||||
if (id != null) { // Don't add files we can't get an
|
||||
// ID for.
|
||||
TranslationUnit tu;
|
||||
if (wkspFile != null)
|
||||
tu = new TranslationUnit(cproject, wkspFile, id);
|
||||
else
|
||||
tu = new ExternalTranslationUnit(cproject, URIUtil.toURI(path), id);
|
||||
|
||||
sourceFiles.add(tu);
|
||||
|
||||
if (!orgPath.equals(filename)) {
|
||||
remappedPaths.put(tu, orgPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sourceFiles.toArray(new TranslationUnit[sourceFiles.size()]);
|
||||
}
|
||||
|
||||
public String getOriginalLocation(ITranslationUnit tu) {
|
||||
String orgLocation = remappedPaths.get(tu);
|
||||
if (orgLocation == null)
|
||||
orgLocation = tu.getPath().toOSString();
|
||||
return orgLocation;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
public class ExecutablesChangeEvent extends PlatformObject implements IExecutablesChangeEvent {
|
||||
|
||||
private Executable[] oldExecutables;
|
||||
private Executable[] newExecutables;
|
||||
|
||||
public ExecutablesChangeEvent(ArrayList<Executable> oldList, ArrayList<Executable> newList) {
|
||||
oldExecutables = oldList.toArray(new Executable[oldList.size()]);
|
||||
newExecutables = newList.toArray(new Executable[newList.size()]);
|
||||
}
|
||||
|
||||
public Executable[] getCurrentExecutables() {
|
||||
return newExecutables;
|
||||
}
|
||||
|
||||
public Executable[] getPreviousExecutables() {
|
||||
return oldExecutables;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
|
||||
/**
|
||||
* The Executables Manager maintains a collection of executables built by all of
|
||||
* the projects in the workspace. Executables are contributed by instances of
|
||||
* IExecutablesProvider.
|
||||
*
|
||||
* @author Ken Ryall
|
||||
*
|
||||
*/
|
||||
public class ExecutablesManager extends PlatformObject {
|
||||
|
||||
private ArrayList<Executable> executables = new ArrayList<Executable>();
|
||||
private List<IExecutablesChangeListener> changeListeners = Collections.synchronizedList(new ArrayList<IExecutablesChangeListener>());
|
||||
private List<ISourceFileRemapping> sourceFileRemappings = Collections.synchronizedList(new ArrayList<ISourceFileRemapping>());
|
||||
private List<IExecutableProvider> executableProviders = Collections.synchronizedList(new ArrayList<IExecutableProvider>());
|
||||
private List<IExecutableImporter> executableImporters = Collections.synchronizedList(new ArrayList<IExecutableImporter>());
|
||||
private boolean refreshNeeded = true;
|
||||
|
||||
private Job refreshJob = new Job("Get Executables") {
|
||||
|
||||
@Override
|
||||
public IStatus run(IProgressMonitor monitor) {
|
||||
refreshExecutables(monitor);
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
|
||||
private static ExecutablesManager executablesManager = null;
|
||||
|
||||
public static ExecutablesManager getExecutablesManager() {
|
||||
if (executablesManager == null)
|
||||
executablesManager = new ExecutablesManager();
|
||||
return executablesManager;
|
||||
}
|
||||
|
||||
public ExecutablesManager() {
|
||||
addSourceFileRemapping(new StandardSourceFileRemapping());
|
||||
addExecutableImporter(new StandardExecutableImporter());
|
||||
addExecutablesProvider(new StandardExecutableProvider());
|
||||
}
|
||||
|
||||
public void addExecutablesChangeListener(IExecutablesChangeListener listener) {
|
||||
changeListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeExecutablesChangeListener(IExecutablesChangeListener listener) {
|
||||
changeListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void addSourceFileRemapping(ISourceFileRemapping remapping) {
|
||||
sourceFileRemappings.add(remapping);
|
||||
}
|
||||
|
||||
public void removeSourceFileRemapping(ISourceFileRemapping remapping) {
|
||||
sourceFileRemappings.remove(remapping);
|
||||
}
|
||||
|
||||
public void addExecutableImporter(IExecutableImporter importer) {
|
||||
executableImporters.add(importer);
|
||||
}
|
||||
|
||||
public void removeExecutableImporter(IExecutableImporter importer) {
|
||||
executableImporters.remove(importer);
|
||||
}
|
||||
|
||||
public void addExecutablesProvider(IExecutableProvider provider) {
|
||||
executableProviders.add(provider);
|
||||
}
|
||||
|
||||
public void removeExecutablesProvider(IExecutableProvider provider) {
|
||||
executableProviders.remove(provider);
|
||||
}
|
||||
|
||||
public IStatus refreshExecutables(IProgressMonitor monitor) {
|
||||
ArrayList<Executable> oldList = executables;
|
||||
executables = new ArrayList<Executable>();
|
||||
synchronized (executableProviders) {
|
||||
monitor.beginTask("Refresh Executables", executableProviders.size());
|
||||
for (IExecutableProvider provider : executableProviders) {
|
||||
executables.addAll(provider.getExecutables(new SubProgressMonitor(monitor, 1)));
|
||||
}
|
||||
monitor.done();
|
||||
}
|
||||
refreshNeeded = false;
|
||||
|
||||
synchronized (changeListeners) {
|
||||
for (IExecutablesChangeListener listener : changeListeners) {
|
||||
listener.executablesChanged(new ExecutablesChangeEvent(oldList, executables) {
|
||||
});
|
||||
}
|
||||
}
|
||||
return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
|
||||
}
|
||||
|
||||
public Executable[] getExecutables() {
|
||||
if (refreshNeeded) {
|
||||
try {
|
||||
refreshJob.schedule();
|
||||
refreshJob.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return executables.toArray(new Executable[executables.size()]);
|
||||
}
|
||||
|
||||
public String remapSourceFile(String filePath) {
|
||||
synchronized (sourceFileRemappings) {
|
||||
for (ISourceFileRemapping remapping : sourceFileRemappings) {
|
||||
String remappedPath = remapping.remapSourceFile(filePath);
|
||||
if (!remappedPath.equals(filePath))
|
||||
return remappedPath;
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void importExecutables(String[] fileNames, IProgressMonitor monitor) {
|
||||
synchronized (executableImporters) {
|
||||
monitor.beginTask("Import Executables", executableImporters.size());
|
||||
for (IExecutableImporter importer : executableImporters) {
|
||||
importer.importExecutables(fileNames, new SubProgressMonitor(monitor, 1));
|
||||
}
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
public ISourceFileRemapping[] getSourceFileRemappings() {
|
||||
return sourceFileRemappings.toArray(new ISourceFileRemapping[sourceFileRemappings.size()]);
|
||||
}
|
||||
|
||||
public IExecutableProvider[] getExecutableProviders() {
|
||||
return executableProviders.toArray(new IExecutableProvider[executableProviders.size()]);
|
||||
}
|
||||
|
||||
public IExecutableImporter[] getExecutableImporters() {
|
||||
return executableImporters.toArray(new IExecutableImporter[executableImporters.size()]);
|
||||
}
|
||||
|
||||
public void scheduleRefresh(IExecutableProvider provider, long delay) {
|
||||
refreshNeeded = true;
|
||||
refreshJob.schedule(delay);
|
||||
}
|
||||
|
||||
public boolean refreshNeeded() {
|
||||
return refreshNeeded;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
public interface IExecutableImporter {
|
||||
|
||||
public abstract void importExecutables(String[] fileNames, IProgressMonitor monitor);
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
/**
|
||||
* IExecutablesProvider supplies a list of executables to the Executables
|
||||
* Manager.
|
||||
*
|
||||
* @author Ken Ryall
|
||||
*
|
||||
*/
|
||||
public interface IExecutableProvider {
|
||||
|
||||
Collection<Executable> getExecutables(IProgressMonitor monitor);
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
public interface IExecutablesChangeEvent {
|
||||
|
||||
public Executable[] getCurrentExecutables();
|
||||
|
||||
public Executable[] getPreviousExecutables();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface IExecutablesChangeListener extends EventListener {
|
||||
|
||||
public void executablesChanged(IExecutablesChangeEvent event);
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
/**
|
||||
* ISourceFileRemapping is used by the Executables Manager when finding missing
|
||||
* source files.
|
||||
*
|
||||
* @author Ken Ryall
|
||||
*
|
||||
*/
|
||||
public interface ISourceFileRemapping {
|
||||
|
||||
String remapSourceFile(String filePath);
|
||||
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||
import org.eclipse.core.filesystem.EFS;
|
||||
import org.eclipse.core.filesystem.IFileStore;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IProjectDescription;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
public class StandardExecutableImporter implements IExecutableImporter {
|
||||
|
||||
public static final String DEBUG_PROJECT_ID = "org.eclipse.cdt.debug"; //$NON-NLS-1$
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.cdt.debug.core.executables.IExecutableImporter#importExecutables(java.lang.String[],
|
||||
* org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
public void importExecutables(String[] fileNames, IProgressMonitor monitor) {
|
||||
monitor.beginTask("Import Executables", fileNames.length);
|
||||
|
||||
IProject exeProject = null;
|
||||
boolean checkProject = false;
|
||||
// Weed out existing ones
|
||||
for (String path : fileNames) {
|
||||
|
||||
try {
|
||||
path = new File(path).getCanonicalPath();
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
if (!executableExists(path)) {
|
||||
if (!checkProject) {
|
||||
// See if the default project exists
|
||||
String defaultProjectName = "Executables";
|
||||
ICProject cProject = CoreModel.getDefault().getCModel().getCProject(defaultProjectName);
|
||||
if (cProject.exists()) {
|
||||
exeProject = cProject.getProject();
|
||||
} else {
|
||||
final String[] ignoreList = { ".project", //$NON-NLS-1$
|
||||
".cdtproject", //$NON-NLS-1$
|
||||
".cproject", //$NON-NLS-1$
|
||||
".cdtbuild", //$NON-NLS-1$
|
||||
".settings", //$NON-NLS-1$
|
||||
};
|
||||
|
||||
IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
IProject newProjectHandle = workspace.getRoot().getProject(defaultProjectName);
|
||||
|
||||
IProjectDescription description = workspace.newProjectDescription(newProjectHandle.getName());
|
||||
description.setLocation(null);
|
||||
IFileStore store;
|
||||
try {
|
||||
store = EFS.getStore(workspace.getRoot().getLocationURI());
|
||||
store = store.getChild(newProjectHandle.getName());
|
||||
for (String deleteName : ignoreList) {
|
||||
IFileStore projFile = store.getChild(deleteName);
|
||||
projFile.delete(EFS.NONE, monitor);
|
||||
}
|
||||
exeProject = CCorePlugin.getDefault().createCProject(description, newProjectHandle, null, DEBUG_PROJECT_ID);
|
||||
} catch (OperationCanceledException e) {
|
||||
e.printStackTrace();
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
checkProject = true;
|
||||
}
|
||||
|
||||
importExecutable(exeProject, path);
|
||||
}
|
||||
monitor.worked(1);
|
||||
}
|
||||
monitor.done();
|
||||
}
|
||||
|
||||
private boolean executableExists(String path) {
|
||||
Executable[] executables = ExecutablesManager.getExecutablesManager().getExecutables();
|
||||
for (Executable executable : executables) {
|
||||
if (executable.getPath().toOSString().equals(path))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void importExecutable(IProject exeProject, String path) {
|
||||
|
||||
IPath location = Path.fromOSString(path);
|
||||
String executableName = location.toFile().getName();
|
||||
IFile exeFile = exeProject.getProject().getFile(executableName);
|
||||
if (!exeFile.exists() && validateBinaryParsers(exeProject, new File(path))) {
|
||||
try {
|
||||
exeFile.createLink(location, 0, null);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isExtensionVisible(IExtension ext) {
|
||||
IConfigurationElement[] elements = ext.getConfigurationElements();
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
IConfigurationElement[] children = elements[i].getChildren("filter"); //$NON-NLS-1$
|
||||
for (int j = 0; j < children.length; j++) {
|
||||
String name = children[j].getAttribute("name"); //$NON-NLS-1$
|
||||
if (name != null && name.equals("visibility")) { //$NON-NLS-1$
|
||||
String value = children[j].getAttribute("value"); //$NON-NLS-1$
|
||||
if (value != null && value.equals("private")) { //$NON-NLS-1$
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false; // invalid extension definition (must have at least
|
||||
// cextension elements)
|
||||
}
|
||||
|
||||
private IBinaryParser instantiateBinaryParser(IExtension ext) {
|
||||
IBinaryParser parser = null;
|
||||
IConfigurationElement[] elements = ext.getConfigurationElements();
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
IConfigurationElement[] children = elements[i].getChildren("run"); //$NON-NLS-1$
|
||||
for (int j = 0; j < children.length; j++) {
|
||||
try {
|
||||
parser = (IBinaryParser) children[j].createExecutableExtension("class");
|
||||
} catch (CoreException e) {
|
||||
CDebugCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
private boolean validateBinaryParsers(IProject exeProject, File file) {
|
||||
IExtension[] binaryParserExtensions;
|
||||
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, CCorePlugin.BINARY_PARSER_SIMPLE_ID);
|
||||
if (point != null) {
|
||||
IExtension[] exts = point.getExtensions();
|
||||
ArrayList<IExtension> extensionsInUse = new ArrayList<IExtension>();
|
||||
for (int i = 0; i < exts.length; i++) {
|
||||
if (isExtensionVisible(exts[i])) {
|
||||
extensionsInUse.add(exts[i]);
|
||||
}
|
||||
}
|
||||
binaryParserExtensions = extensionsInUse.toArray(new IExtension[extensionsInUse.size()]);
|
||||
|
||||
for (int i = 0; i < binaryParserExtensions.length; i++) {
|
||||
IBinaryParser parser = instantiateBinaryParser(binaryParserExtensions[i]);
|
||||
if (isBinary(file, parser)) {
|
||||
String parserID = binaryParserExtensions[i].getUniqueIdentifier();
|
||||
// Make sure the project has this parser
|
||||
ICProjectDescription pd = CCorePlugin.getDefault().getProjectDescription(exeProject);
|
||||
try {
|
||||
pd.getDefaultSettingConfiguration().create(CCorePlugin.BINARY_PARSER_UNIQ_ID, parserID);
|
||||
CCorePlugin.getDefault().setProjectDescription(exeProject, pd, true, new NullProgressMonitor());
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isBinary(File file, IBinaryParser parser) {
|
||||
if (parser != null) {
|
||||
try {
|
||||
IBinaryParser.IBinaryFile bin = parser.getBinary(new Path(file.getAbsolutePath()));
|
||||
return bin != null && (bin.getType() == IBinaryParser.IBinaryFile.EXECUTABLE || bin.getType() == IBinaryParser.IBinaryFile.SHARED);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
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.ICProject;
|
||||
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
|
||||
import org.eclipse.cdt.internal.core.model.CModelManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||
import org.eclipse.core.resources.IResourceChangeListener;
|
||||
import org.eclipse.core.resources.IResourceDelta;
|
||||
import org.eclipse.core.resources.IResourceDeltaVisitor;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
public class StandardExecutableProvider implements IResourceChangeListener, ICProjectDescriptionListener, IExecutableProvider {
|
||||
|
||||
private ArrayList<Executable> executables = new ArrayList<Executable>();
|
||||
|
||||
public StandardExecutableProvider() {
|
||||
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
|
||||
CoreModel.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(this,
|
||||
CProjectDescriptionEvent.DATA_APPLIED | CProjectDescriptionEvent.LOADDED);
|
||||
}
|
||||
|
||||
public void resourceChanged(IResourceChangeEvent event) {
|
||||
|
||||
// refresh when projects are opened or closed. note that deleted
|
||||
// projects are handled later
|
||||
// in this method. new projects are handled in handleEvent.
|
||||
// resource changed events always start at the workspace root, so
|
||||
// projects
|
||||
// are the next level down
|
||||
IResourceDelta[] projects = event.getDelta().getAffectedChildren();
|
||||
for (IResourceDelta projectDelta : projects) {
|
||||
if ((projectDelta.getFlags() & IResourceDelta.OPEN) != 0) {
|
||||
if (projectDelta.getKind() == IResourceDelta.CHANGED) {
|
||||
// project was opened or closed
|
||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(this, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final StandardExecutableProvider provider = this;
|
||||
event.getDelta().accept(new IResourceDeltaVisitor() {
|
||||
|
||||
public boolean visit(IResourceDelta delta) throws CoreException {
|
||||
if (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.REMOVED) {
|
||||
IResource deltaResource = delta.getResource();
|
||||
if (deltaResource != null) {
|
||||
boolean refresh = false;
|
||||
if (delta.getKind() == IResourceDelta.REMOVED && deltaResource instanceof IProject) {
|
||||
// project deleted
|
||||
refresh = true;
|
||||
} else {
|
||||
// see if a binary has been added/removed
|
||||
IPath resourcePath = delta.getResource().getLocation();
|
||||
if (resourcePath != null && Executable.isExecutableFile(resourcePath)) {
|
||||
refresh = true;
|
||||
}
|
||||
}
|
||||
if (refresh) {
|
||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(provider, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void handleEvent(CProjectDescriptionEvent event) {
|
||||
// this handles the cases where the active build configuration changes,
|
||||
// and when new
|
||||
// projects are created.
|
||||
boolean refresh = false;
|
||||
|
||||
int eventType = event.getEventType();
|
||||
|
||||
if (eventType == CProjectDescriptionEvent.DATA_APPLIED) {
|
||||
// see if the active build config has changed
|
||||
ICProjectDescription newDesc = event.getNewCProjectDescription();
|
||||
ICProjectDescription oldDesc = event.getOldCProjectDescription();
|
||||
if (oldDesc != null && newDesc != null) {
|
||||
String newConfigName = newDesc.getActiveConfiguration().getName();
|
||||
String oldConfigName = oldDesc.getActiveConfiguration().getName();
|
||||
refresh = (!newConfigName.equals(oldConfigName));
|
||||
} else if (newDesc != null && oldDesc == null) {
|
||||
// project just created
|
||||
refresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (refresh) {
|
||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(this, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Executable> getExecutables(IProgressMonitor monitor) {
|
||||
executables.clear();
|
||||
|
||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IProject[] projects = root.getProjects();
|
||||
|
||||
monitor.beginTask("Checking C/C++ Projects", projects.length);
|
||||
|
||||
for (IProject project : projects) {
|
||||
|
||||
if (monitor.isCanceled())
|
||||
break;
|
||||
|
||||
try {
|
||||
if (CoreModel.hasCNature(project)) {
|
||||
CModelManager manager = CModelManager.getDefault();
|
||||
ICProject cproject = manager.create(project);
|
||||
try {
|
||||
IBinary[] binaries = cproject.getBinaryContainer().getBinaries();
|
||||
for (IBinary binary : binaries) {
|
||||
if (binary.isExecutable() || binary.isSharedLib()) {
|
||||
IPath exePath = binary.getResource().getLocation();
|
||||
if (exePath == null)
|
||||
exePath = binary.getPath();
|
||||
Executable exe = new Executable(exePath, project, binary.getResource());
|
||||
executables.add(exe);
|
||||
}
|
||||
}
|
||||
} catch (CModelException e) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
monitor.worked(1);
|
||||
}
|
||||
monitor.done();
|
||||
|
||||
return executables;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.core.executables;
|
||||
|
||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||
import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator;
|
||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchManager;
|
||||
import org.eclipse.debug.core.model.ISourceLocator;
|
||||
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
|
||||
|
||||
public class StandardSourceFileRemapping implements ISourceFileRemapping {
|
||||
|
||||
public String remapSourceFile(String filePath) {
|
||||
|
||||
try {
|
||||
Object[] foundElements = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().findSourceElements(filePath);
|
||||
|
||||
if (foundElements.length == 0) {
|
||||
Object foundElement = null;
|
||||
ILaunchManager launchMgr = DebugPlugin.getDefault().getLaunchManager();
|
||||
ILaunch[] launches = launchMgr.getLaunches();
|
||||
for (ILaunch launch : launches) {
|
||||
ISourceLocator locator = launch.getSourceLocator();
|
||||
if (locator instanceof ICSourceLocator || locator instanceof CSourceLookupDirector) {
|
||||
if (locator instanceof ICSourceLocator)
|
||||
foundElement = ((ICSourceLocator) locator).findSourceElement(filePath);
|
||||
else
|
||||
foundElement = ((CSourceLookupDirector) locator).getSourceElement(filePath);
|
||||
}
|
||||
}
|
||||
if (foundElement != null)
|
||||
foundElements = new Object[] { foundElement };
|
||||
}
|
||||
|
||||
if (foundElements.length == 1 && foundElements[0] instanceof LocalFileStorage) {
|
||||
LocalFileStorage newLocation = (LocalFileStorage) foundElements[0];
|
||||
filePath = newLocation.getFullPath().toOSString();
|
||||
}
|
||||
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
}
|
|
@ -24,7 +24,9 @@ import org.eclipse.core.resources.ResourcesPlugin;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceContainerType;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
|
||||
import org.eclipse.debug.core.sourcelookup.containers.AbstractSourceContainer;
|
||||
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
|
||||
|
||||
|
@ -48,14 +50,22 @@ public class AbsolutePathSourceContainer extends AbstractSourceContainer {
|
|||
return wfiles;
|
||||
|
||||
// The file is not already in the workspace so try to create an external translation unit for it.
|
||||
String projectName = getDirector().getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
|
||||
if (projectName != "") {
|
||||
ICProject project = CoreModel.getDefault().getCModel().getCProject(projectName);
|
||||
if (project != null)
|
||||
ISourceLookupDirector director = getDirector();
|
||||
if (director != null)
|
||||
{
|
||||
ILaunchConfiguration launch = director.getLaunchConfiguration();
|
||||
if (launch != null)
|
||||
{
|
||||
IPath path = Path.fromOSString(file.getCanonicalPath());
|
||||
String id = CoreModel.getRegistedContentTypeId(project.getProject(), path.lastSegment());
|
||||
return new ExternalTranslationUnit[] { new ExternalTranslationUnit(project, file.toURI(), id) };
|
||||
String projectName = getDirector().getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
|
||||
if (projectName != "") {
|
||||
ICProject project = CoreModel.getDefault().getCModel().getCProject(projectName);
|
||||
if (project != null)
|
||||
{
|
||||
IPath path = Path.fromOSString(file.getCanonicalPath());
|
||||
String id = CoreModel.getRegistedContentTypeId(project.getProject(), path.lastSegment());
|
||||
return new ExternalTranslationUnit[] { new ExternalTranslationUnit(project, file.toURI(), id) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) { // ignore if getCanonicalPath throws
|
||||
|
|
|
@ -16,6 +16,7 @@ Export-Package:
|
|||
org.eclipse.cdt.debug.internal.ui.sourcelookup,
|
||||
org.eclipse.cdt.debug.internal.ui.views,
|
||||
org.eclipse.cdt.debug.internal.ui.views.disassembly,
|
||||
org.eclipse.cdt.debug.internal.ui.views.executables,
|
||||
org.eclipse.cdt.debug.internal.ui.views.modules,
|
||||
org.eclipse.cdt.debug.internal.ui.views.signals,
|
||||
org.eclipse.cdt.debug.ui,
|
||||
|
|
BIN
debug/org.eclipse.cdt.debug.ui/icons/dlcl16/columns.gif
Normal file
After Width: | Height: | Size: 565 B |
BIN
debug/org.eclipse.cdt.debug.ui/icons/dlcl16/import.gif
Normal file
After Width: | Height: | Size: 327 B |
BIN
debug/org.eclipse.cdt.debug.ui/icons/dlcl16/refresh.gif
Normal file
After Width: | Height: | Size: 205 B |
BIN
debug/org.eclipse.cdt.debug.ui/icons/elcl16/columns.gif
Normal file
After Width: | Height: | Size: 564 B |
BIN
debug/org.eclipse.cdt.debug.ui/icons/elcl16/import.gif
Normal file
After Width: | Height: | Size: 327 B |
BIN
debug/org.eclipse.cdt.debug.ui/icons/elcl16/refresh.gif
Normal file
After Width: | Height: | Size: 330 B |
BIN
debug/org.eclipse.cdt.debug.ui/icons/obj16/exec_view_obj.gif
Normal file
After Width: | Height: | Size: 378 B |
|
@ -15,6 +15,7 @@ providerName=Eclipse.org
|
|||
MemoryView.name=Memory
|
||||
ModulesView.name=Modules
|
||||
SignalsView.name=Signals
|
||||
ExecutablesView.name=Executables
|
||||
|
||||
CDebuggerPage.name=C Debugger UI Page
|
||||
MemoryPreferencePage.name=Memory View
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.views">
|
||||
<view
|
||||
name="%ExecutablesView.name"
|
||||
icon="icons/obj16/exec_view_obj.gif"
|
||||
category="org.eclipse.debug.ui"
|
||||
class="org.eclipse.cdt.debug.internal.ui.views.executables.ExecutablesView"
|
||||
id="org.eclipse.cdt.debug.ui.executablesView">
|
||||
</view>
|
||||
<view
|
||||
name="%SignalsView.name"
|
||||
icon="icons/view16/signals_view.gif"
|
||||
|
@ -89,6 +96,14 @@
|
|||
<viewShortcut
|
||||
id="org.eclipse.ui.views.ProblemView">
|
||||
</viewShortcut>
|
||||
<view
|
||||
id="org.eclipse.cdt.debug.ui.executablesView"
|
||||
relative="org.eclipse.ui.console.ConsoleView"
|
||||
relationship="stack">
|
||||
</view>
|
||||
<viewShortcut
|
||||
id="org.eclipse.cdt.debug.internal.ui.views.executables.ExecutablesView">
|
||||
</viewShortcut>
|
||||
<actionSet
|
||||
id="org.eclipse.cdt.debug.ui.debugActionSet">
|
||||
</actionSet>
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.jface.viewers.ViewerComparator;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.TreeColumn;
|
||||
|
||||
/**
|
||||
* Base viewer used by both the executables viewers and the source files viewer.
|
||||
*/
|
||||
abstract class BaseViewer extends TreeViewer {
|
||||
|
||||
// Common columns
|
||||
protected TreeColumn nameColumn;
|
||||
protected TreeColumn locationColumn;
|
||||
protected TreeColumn sizeColumn;
|
||||
protected TreeColumn modifiedColumn;
|
||||
protected TreeColumn typeColumn;
|
||||
|
||||
private static final int NUM_COLUMNS = 7;
|
||||
int column_order[] = new int[NUM_COLUMNS];
|
||||
|
||||
private ExecutablesView executablesView;
|
||||
|
||||
class ColumnSelectionAdapter extends SelectionAdapter {
|
||||
|
||||
private int selector;
|
||||
|
||||
public ColumnSelectionAdapter(int selector) {
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
column_order[selector] *= -1;
|
||||
ViewerComparator comparator = getViewerComparator(selector);
|
||||
setComparator(comparator);
|
||||
executablesView.getMemento().putInteger(ExecutablesView.P_ORDER_VALUE_SF, column_order[selector]);
|
||||
executablesView.getMemento().putInteger(ExecutablesView.P_ORDER_TYPE_SF, selector);
|
||||
setColumnSorting((TreeColumn) e.getSource(), column_order[selector]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BaseViewer(ExecutablesView view, Composite parent, int style) {
|
||||
super(parent, style);
|
||||
executablesView = view;
|
||||
}
|
||||
|
||||
public ExecutablesView getExecutablesView() {
|
||||
return executablesView;
|
||||
}
|
||||
|
||||
protected void packColumns() {
|
||||
TreeColumn[] columns = getTree().getColumns();
|
||||
for (TreeColumn treeColumn : columns) {
|
||||
if (treeColumn.getWidth() > 0) {
|
||||
treeColumn.pack();
|
||||
treeColumn.setWidth(treeColumn.getWidth() + ExecutablesView.COLUMN_WIDTH_PADDING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setColumnSorting(TreeColumn column, int order) {
|
||||
getTree().setSortColumn(column);
|
||||
getTree().setSortDirection(order == ExecutablesView.ASCENDING ? SWT.UP : SWT.DOWN);
|
||||
}
|
||||
|
||||
abstract protected ViewerComparator getViewerComparator(int sortType);
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jface.viewers.ColumnLabelProvider;
|
||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerCell;
|
||||
|
||||
class ExecutablesContentProvider extends ColumnLabelProvider implements IStructuredContentProvider, ITreeContentProvider {
|
||||
|
||||
private TreeViewer viewer;
|
||||
|
||||
public ExecutablesContentProvider(TreeViewer viewer) {
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
public Object[] getElements(final Object inputElement) {
|
||||
if (inputElement instanceof ExecutablesManager) {
|
||||
final ExecutablesManager em = (ExecutablesManager) inputElement;
|
||||
if (em.refreshNeeded()) {
|
||||
// do this asynchronously. just return an empty array
|
||||
// immediately, and then refresh the view
|
||||
// once the list of executables has been calculated. this can
|
||||
// take a while and we don't want
|
||||
// to block the UI.
|
||||
Job refreshJob = new Job("Fetching executables") {
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
IStatus status = em.refreshExecutables(monitor);
|
||||
|
||||
// Are we in the UIThread? If so spin it until we are
|
||||
// done
|
||||
if (viewer.getControl().getDisplay().getThread() == Thread.currentThread()) {
|
||||
viewer.refresh(inputElement);
|
||||
} else {
|
||||
viewer.getControl().getDisplay().asyncExec(new Runnable() {
|
||||
public void run() {
|
||||
viewer.refresh(inputElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
monitor.done();
|
||||
return status;
|
||||
}
|
||||
};
|
||||
|
||||
refreshJob.schedule();
|
||||
|
||||
} else {
|
||||
return em.getExecutables();
|
||||
}
|
||||
}
|
||||
return new Object[] {};
|
||||
}
|
||||
|
||||
public Object getParent(Object element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasChildren(Object element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(ViewerCell cell) {
|
||||
super.update(cell);
|
||||
Object element = cell.getElement();
|
||||
if (element instanceof Executable) {
|
||||
Executable exe = (Executable) element;
|
||||
String cellText = exe.getName();
|
||||
if (cell.getColumnIndex() == 1)
|
||||
cellText = exe.getProject().getName();
|
||||
else if (cell.getColumnIndex() == 2)
|
||||
cellText = exe.getPath().toOSString();
|
||||
else if (cell.getColumnIndex() == 3) {
|
||||
cellText = "";
|
||||
IPath path = exe.getPath();
|
||||
if (path != null && path.toFile().exists()) {
|
||||
long fileLength = path.toFile().length();
|
||||
cellText = Long.toString(fileLength);
|
||||
}
|
||||
cell.setImage(null);
|
||||
} else if (cell.getColumnIndex() == 4) {
|
||||
cellText = "";
|
||||
IPath path = exe.getPath();
|
||||
if (path != null && path.toFile().exists()) {
|
||||
long modified = path.toFile().lastModified();
|
||||
cellText = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(new Date(modified));
|
||||
}
|
||||
cell.setImage(null);
|
||||
} else if (cell.getColumnIndex() == 5) {
|
||||
cellText = exe.getPath().getFileExtension().toUpperCase();
|
||||
}
|
||||
cell.setText(cellText);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Object element) {
|
||||
if (element instanceof Executable) {
|
||||
return ((Executable) element).getName();
|
||||
} else
|
||||
return super.getText(element);
|
||||
}
|
||||
|
||||
public Object[] getChildren(Object parentElement) {
|
||||
return new Object[] {};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,500 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
||||
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Preferences;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.IToolBarManager;
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.LabelProvider;
|
||||
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.window.Window;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.SashForm;
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.swt.widgets.TreeColumn;
|
||||
import org.eclipse.ui.IActionBars;
|
||||
import org.eclipse.ui.IMemento;
|
||||
import org.eclipse.ui.IViewSite;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.XMLMemento;
|
||||
import org.eclipse.ui.dialogs.ListSelectionDialog;
|
||||
import org.eclipse.ui.part.ViewPart;
|
||||
|
||||
/**
|
||||
* ExecutablesView displays a list of executable files either in the workspace
|
||||
* or created by projects in the workspace. The list of executables comes from
|
||||
* the ExecutablesManager. This view has two subviews: one that shows the list
|
||||
* of executables and another that shows the list of source files in the
|
||||
* selected executable.
|
||||
*
|
||||
*/
|
||||
public class ExecutablesView extends ViewPart {
|
||||
|
||||
/**
|
||||
* Settings for the view including the sorted column for the sub views and
|
||||
* the list of visible columns.
|
||||
*/
|
||||
|
||||
public static final String P_ORDER_TYPE_EXE = "orderTypeEXE"; //$NON-NLS-1$
|
||||
public static final String P_ORDER_VALUE_EXE = "orderValueEXE"; //$NON-NLS-1$
|
||||
public static final String P_ORDER_TYPE_SF = "orderTypeSF"; //$NON-NLS-1$
|
||||
public static final String P_ORDER_VALUE_SF = "orderValueSF"; //$NON-NLS-1$
|
||||
public static final String P_VISIBLE_COLUMNS = "visibleColumns"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Constants for the columns.
|
||||
*/
|
||||
|
||||
public final static int NAME = 0x0;
|
||||
public final static int PROJECT = 0x1;
|
||||
public final static int LOCATION = 0x2;
|
||||
public final static int ORG_LOCATION = 0x3;
|
||||
public final static int SIZE = 0x4;
|
||||
public final static int MODIFIED = 0x5;
|
||||
public final static int TYPE = 0x6;
|
||||
|
||||
/**
|
||||
* Constants for the column sort order.
|
||||
*/
|
||||
|
||||
public static int ASCENDING = 1;
|
||||
public static int DESCENDING = -1;
|
||||
|
||||
/**
|
||||
* Display constants and icons.
|
||||
*/
|
||||
|
||||
public final static String ICONS_PATH = "icons/"; //$NON-NLS-1$
|
||||
public static final String EXECUTABLES_VIEW_CONTEXT = "org.eclipse.cdt.debug.ui.executables_View_context"; //$NON-NLS-1$;
|
||||
private static final String PATH_LCL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$
|
||||
private static final String PATH_LCL_DISABLED = ICONS_PATH + "dlcl16/"; //$NON-NLS-1$
|
||||
public static final ImageDescriptor DESC_REFRESH = create(PATH_LCL, "refresh.gif"); //$NON-NLS-1$
|
||||
public static final ImageDescriptor DESC_REFRESH_DISABLED = create(PATH_LCL_DISABLED, "refresh.gif"); //$NON-NLS-1$
|
||||
public static final ImageDescriptor DESC_IMPORT = create(PATH_LCL, "import.gif"); //$NON-NLS-1$
|
||||
public static final ImageDescriptor DESC_IMPORT_DISABLED = create(PATH_LCL_DISABLED, "import.gif"); //$NON-NLS-1$
|
||||
public static final ImageDescriptor DESC_COLUMNS = create(PATH_LCL, "columns.gif"); //$NON-NLS-1$
|
||||
public static final ImageDescriptor DESC_COLUMNS_DISABLED = create(PATH_LCL_DISABLED, "columns.gif"); //$NON-NLS-1$
|
||||
public static final int COLUMN_WIDTH_PADDING = 24;
|
||||
|
||||
private static ImageDescriptor create(String prefix, String name) {
|
||||
return ImageDescriptor.createFromURL(makeIconURL(prefix, name));
|
||||
}
|
||||
|
||||
private static URL makeIconURL(String prefix, String name) {
|
||||
String path = "$nl$/" + prefix + name; //$NON-NLS-1$
|
||||
return FileLocator.find(CDebugUIPlugin.getDefault().getBundle(), new Path(path), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete list of column names for both sub views. These are not display
|
||||
* names and should not be localized. Display names are set when the columns
|
||||
* are created in the sub views.
|
||||
*/
|
||||
private String[] columnNames = { "Executable Name", "Executable Project", "Executable Location", "Executable Size", "Executable Date",
|
||||
"Executable Type", "Source File Name", "Source File Location", "Source File Original Location", "Source File Size", "Source File Date",
|
||||
"Source File Type" };
|
||||
|
||||
/**
|
||||
* Not all the columns are visible by default. Here are the ones that are.
|
||||
*/
|
||||
private String defaultVisibleColumns = "Executable Name,Executable Project,Executable Location,Source File Name,Source File Location";
|
||||
private TreeColumn[] allColumns = new TreeColumn[columnNames.length];
|
||||
|
||||
/**
|
||||
* Configures the list of columns show in the view.
|
||||
*/
|
||||
public class ConfigureColumnsAction extends Action {
|
||||
|
||||
public static final String CONFIGURE_COLUMNS_DIALOG = "org.eclipse.cdt.debug.ui.configure_columns_dialog_context"; //$NON-NLS-1$;
|
||||
public static final String CONFIGURE_COLUMNS_ACTION = "org.eclipse.cdt.debug.ui.configure_columns_action_context"; //$NON-NLS-1$;
|
||||
|
||||
class ColumnContentProvider implements IStructuredContentProvider {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
|
||||
*/
|
||||
public Object[] getElements(Object inputElement) {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
|
||||
* java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ColumnLabelProvider extends LabelProvider {
|
||||
|
||||
public String getText(Object element) {
|
||||
return (String) element;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ConfigureColumnsAction() {
|
||||
setText("Configure Columns");
|
||||
setId(CDebugUIPlugin.getUniqueIdentifier() + ".ConfigureColumnsAction"); //$NON-NLS-1$
|
||||
PlatformUI.getWorkbench().getHelpSystem().setHelp(this, CONFIGURE_COLUMNS_ACTION);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.action.Action#run()
|
||||
*/
|
||||
public void run() {
|
||||
ListSelectionDialog dialog = new ListSelectionDialog(ExecutablesView.this.getExecutablesViewer().getTree().getShell(), this,
|
||||
new ColumnContentProvider(), new ColumnLabelProvider(), "Select the columns to show");
|
||||
PlatformUI.getWorkbench().getHelpSystem().setHelp(this, CONFIGURE_COLUMNS_DIALOG);
|
||||
String[] visibleColumns = getVisibleColumns();
|
||||
List<String> initialSelection = new ArrayList<String>(visibleColumns.length);
|
||||
for (int i = 0; i < visibleColumns.length; i++) {
|
||||
initialSelection.add(visibleColumns[i]);
|
||||
}
|
||||
dialog.setTitle("Configure COlumns");
|
||||
dialog.setInitialElementSelections(initialSelection);
|
||||
if (dialog.open() == Window.OK) {
|
||||
Object[] result = dialog.getResult();
|
||||
String[] ids = new String[result.length];
|
||||
System.arraycopy(result, 0, ids, 0, result.length);
|
||||
setVisibleColumns(ids);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub viewers and trees
|
||||
*/
|
||||
private SourceFilesViewer sourceFilesViewer;
|
||||
private ExecutablesViewer executablesViewer;
|
||||
|
||||
/**
|
||||
* Associated Actions
|
||||
*/
|
||||
Action refreshAction;
|
||||
Action importAction;
|
||||
private Action configureColumnsAction;
|
||||
|
||||
private IMemento memento;
|
||||
|
||||
/**
|
||||
* Create contents of the Executables View
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
@Override
|
||||
public void createPartControl(Composite parent) {
|
||||
Composite container = new Composite(parent, SWT.NONE);
|
||||
container.setLayout(new FillLayout());
|
||||
|
||||
final SashForm sashForm = new SashForm(container, SWT.NONE);
|
||||
|
||||
// Create the two sub viewers.
|
||||
executablesViewer = new ExecutablesViewer(this, sashForm, SWT.FULL_SELECTION + SWT.BORDER);
|
||||
ExecutablesManager.getExecutablesManager().addExecutablesChangeListener(executablesViewer);
|
||||
sourceFilesViewer = new SourceFilesViewer(this, sashForm, SWT.BORDER);
|
||||
|
||||
sashForm.setWeights(new int[] { 1, 1 });
|
||||
|
||||
// Keep a combined list of all the columns so
|
||||
// we can easily operate on them all.
|
||||
allColumns[0] = executablesViewer.nameColumn;
|
||||
allColumns[1] = executablesViewer.projectColumn;
|
||||
allColumns[2] = executablesViewer.locationColumn;
|
||||
allColumns[3] = executablesViewer.sizeColumn;
|
||||
allColumns[4] = executablesViewer.modifiedColumn;
|
||||
allColumns[5] = executablesViewer.typeColumn;
|
||||
allColumns[6] = sourceFilesViewer.nameColumn;
|
||||
allColumns[7] = sourceFilesViewer.locationColumn;
|
||||
allColumns[8] = sourceFilesViewer.originalLocationColumn;
|
||||
allColumns[9] = sourceFilesViewer.sizeColumn;
|
||||
allColumns[10] = sourceFilesViewer.modifiedColumn;
|
||||
allColumns[11] = sourceFilesViewer.typeColumn;
|
||||
|
||||
createActions();
|
||||
|
||||
// When the selection changes in the executables list
|
||||
// update the source files viewer
|
||||
executablesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
||||
|
||||
public void selectionChanged(SelectionChangedEvent event) {
|
||||
ISelection newSelection = event.getSelection();
|
||||
if (newSelection instanceof IStructuredSelection) {
|
||||
Object firstElement = ((IStructuredSelection) newSelection).getFirstElement();
|
||||
sourceFilesViewer.setInput(firstElement);
|
||||
if (firstElement instanceof Executable) {
|
||||
sourceFilesViewer.packColumns();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the list of visible columns
|
||||
if (memento.getString(P_VISIBLE_COLUMNS).length() > 0) {
|
||||
String[] visibleColumns = memento.getString(P_VISIBLE_COLUMNS).split(",");
|
||||
setVisibleColumns(visibleColumns);
|
||||
} else {
|
||||
setVisibleColumns(defaultVisibleColumns.split(","));
|
||||
}
|
||||
sourceFilesViewer.packColumns();
|
||||
|
||||
PlatformUI.getWorkbench().getHelpSystem().setHelp(container, EXECUTABLES_VIEW_CONTEXT);
|
||||
}
|
||||
|
||||
private void setVisibleColumns(String[] ids) {
|
||||
List<String> visibleNames = Arrays.asList(ids);
|
||||
for (int i = 0; i < columnNames.length; i++) {
|
||||
makeColumnVisible(visibleNames.contains(columnNames[i]), allColumns[i]);
|
||||
}
|
||||
|
||||
StringBuffer visibleColumns = new StringBuffer();
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
if (i > 0)
|
||||
visibleColumns.append(",");
|
||||
visibleColumns.append(ids[i]);
|
||||
}
|
||||
memento.putString(P_VISIBLE_COLUMNS, visibleColumns.toString());
|
||||
}
|
||||
|
||||
private void makeColumnVisible(boolean visible, TreeColumn column) {
|
||||
boolean isVisible = column.getWidth() > 0;
|
||||
if (isVisible != visible) {
|
||||
if (visible) {
|
||||
column.setResizable(true);
|
||||
column.pack();
|
||||
column.setWidth(column.getWidth() + COLUMN_WIDTH_PADDING);
|
||||
} else {
|
||||
column.setWidth(0);
|
||||
column.setResizable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getVisibleColumns() {
|
||||
ArrayList<String> visibleNames = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < columnNames.length; i++) {
|
||||
if (allColumns[i].getWidth() > 0)
|
||||
visibleNames.add(columnNames[i]);
|
||||
}
|
||||
|
||||
return visibleNames.toArray(new String[visibleNames.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the actions to refresh, import, and configure the columns
|
||||
*/
|
||||
private void createActions() {
|
||||
IActionBars bars = getViewSite().getActionBars();
|
||||
IToolBarManager toolBarManager = bars.getToolBarManager();
|
||||
|
||||
refreshAction = createRefreshAction();
|
||||
toolBarManager.add(refreshAction);
|
||||
|
||||
importAction = createImportAction();
|
||||
toolBarManager.add(importAction);
|
||||
|
||||
configureColumnsAction = createConfigureColumnsAction();
|
||||
toolBarManager.add(configureColumnsAction);
|
||||
|
||||
}
|
||||
|
||||
private Action createConfigureColumnsAction() {
|
||||
ConfigureColumnsAction action = new ConfigureColumnsAction();
|
||||
action.setToolTipText("Columns");
|
||||
action.setImageDescriptor(ExecutablesView.DESC_COLUMNS);
|
||||
action.setDisabledImageDescriptor(ExecutablesView.DESC_COLUMNS_DISABLED);
|
||||
action.setEnabled(true);
|
||||
return action;
|
||||
}
|
||||
|
||||
protected void importExecutables(final String[] fileNames) {
|
||||
if (fileNames.length > 0) {
|
||||
|
||||
Job importJob = new Job("Import Executables") {
|
||||
|
||||
@Override
|
||||
public IStatus run(IProgressMonitor monitor) {
|
||||
ExecutablesManager.getExecutablesManager().importExecutables(fileNames, monitor);
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
importJob.schedule();
|
||||
}
|
||||
}
|
||||
|
||||
private Action createImportAction() {
|
||||
Action action = new Action("Import") {
|
||||
public void run() {
|
||||
FileDialog dialog = new FileDialog(getViewSite().getShell(), SWT.NONE);
|
||||
dialog.setText("Select an executable file");
|
||||
String res = dialog.open();
|
||||
if (res != null) {
|
||||
if (Platform.getOS().equals(Platform.OS_MACOSX) && res.endsWith(".app")) {
|
||||
// On Mac OS X the file dialog will let you select the
|
||||
// package but not the executable inside.
|
||||
Path macPath = new Path(res);
|
||||
res = res + "/Contents/MacOS/" + macPath.lastSegment();
|
||||
res = res.substring(0, res.length() - 4);
|
||||
}
|
||||
importExecutables(new String[] { res });
|
||||
}
|
||||
}
|
||||
};
|
||||
action.setToolTipText("Import an executable file");
|
||||
action.setImageDescriptor(ExecutablesView.DESC_IMPORT);
|
||||
action.setDisabledImageDescriptor(ExecutablesView.DESC_IMPORT_DISABLED);
|
||||
action.setEnabled(true);
|
||||
return action;
|
||||
}
|
||||
|
||||
private Action createRefreshAction() {
|
||||
Action action = new Action("Refresh") {
|
||||
public void run() {
|
||||
ExecutablesManager.getExecutablesManager().scheduleRefresh(null, 0);
|
||||
}
|
||||
};
|
||||
action.setToolTipText("Refresh the list of executables");
|
||||
action.setImageDescriptor(ExecutablesView.DESC_REFRESH);
|
||||
action.setDisabledImageDescriptor(ExecutablesView.DESC_REFRESH_DISABLED);
|
||||
action.setEnabled(true);
|
||||
return action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocus() {
|
||||
// Set the focus
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IViewSite site, IMemento memento) throws PartInitException {
|
||||
if (memento == null)
|
||||
this.memento = XMLMemento.createWriteRoot("EXECUTABLESVIEW"); //$NON-NLS-1$
|
||||
else
|
||||
this.memento = memento;
|
||||
super.init(site, memento);
|
||||
readSettings();
|
||||
}
|
||||
|
||||
private Preferences getViewPreferences() {
|
||||
return CDebugUIPlugin.getDefault().getPluginPreferences();
|
||||
}
|
||||
|
||||
private void initializeMemento() {
|
||||
memento.putInteger(P_ORDER_VALUE_EXE, DESCENDING);
|
||||
memento.putInteger(P_ORDER_TYPE_EXE, NAME);
|
||||
memento.putInteger(P_ORDER_VALUE_SF, DESCENDING);
|
||||
memento.putInteger(P_ORDER_TYPE_SF, NAME);
|
||||
memento.putString(P_VISIBLE_COLUMNS, defaultVisibleColumns);
|
||||
}
|
||||
|
||||
private void readSettings() {
|
||||
Preferences p = getViewPreferences();
|
||||
if (p == null) {
|
||||
initializeMemento();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int order = p.getInt(P_ORDER_VALUE_EXE);
|
||||
memento.putInteger(P_ORDER_VALUE_EXE, order == 0 ? DESCENDING : order);
|
||||
memento.putInteger(P_ORDER_TYPE_EXE, p.getInt(P_ORDER_TYPE_EXE));
|
||||
order = p.getInt(P_ORDER_VALUE_SF);
|
||||
memento.putInteger(P_ORDER_VALUE_SF, order == 0 ? DESCENDING : order);
|
||||
memento.putInteger(P_ORDER_TYPE_SF, p.getInt(P_ORDER_TYPE_SF));
|
||||
memento.putString(P_VISIBLE_COLUMNS, p.getString(P_VISIBLE_COLUMNS));
|
||||
} catch (NumberFormatException e) {
|
||||
memento.putInteger(P_ORDER_TYPE_EXE, NAME);
|
||||
memento.putInteger(P_ORDER_VALUE_EXE, DESCENDING);
|
||||
memento.putInteger(P_ORDER_TYPE_SF, NAME);
|
||||
memento.putInteger(P_ORDER_VALUE_SF, DESCENDING);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSettings() {
|
||||
Preferences preferences = getViewPreferences();
|
||||
int order = memento.getInteger(P_ORDER_VALUE_EXE).intValue();
|
||||
preferences.setValue(P_ORDER_VALUE_EXE, order == 0 ? DESCENDING : order);
|
||||
preferences.setValue(P_ORDER_TYPE_EXE, memento.getInteger(P_ORDER_TYPE_EXE).intValue());
|
||||
order = memento.getInteger(P_ORDER_VALUE_SF).intValue();
|
||||
preferences.setValue(P_ORDER_VALUE_SF, order == 0 ? DESCENDING : order);
|
||||
preferences.setValue(P_ORDER_TYPE_SF, memento.getInteger(P_ORDER_TYPE_SF).intValue());
|
||||
preferences.setValue(P_VISIBLE_COLUMNS, memento.getString(P_VISIBLE_COLUMNS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveState(IMemento memento) {
|
||||
if (this.memento == null || memento == null)
|
||||
return;
|
||||
memento.putMemento(this.memento);
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
public SourceFilesViewer getSourceFilesViewer() {
|
||||
return sourceFilesViewer;
|
||||
}
|
||||
|
||||
public ExecutablesViewer getExecutablesViewer() {
|
||||
return executablesViewer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
ExecutablesManager.getExecutablesManager().removeExecutablesChangeListener(executablesViewer);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public IMemento getMemento() {
|
||||
return memento;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
|
||||
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeEvent;
|
||||
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.jface.action.IMenuListener;
|
||||
import org.eclipse.jface.action.IMenuManager;
|
||||
import org.eclipse.jface.action.MenuManager;
|
||||
import org.eclipse.jface.action.Separator;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerComparator;
|
||||
import org.eclipse.jface.viewers.ViewerDropAdapter;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.dnd.DND;
|
||||
import org.eclipse.swt.dnd.FileTransfer;
|
||||
import org.eclipse.swt.dnd.Transfer;
|
||||
import org.eclipse.swt.dnd.TransferData;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.TreeColumn;
|
||||
import org.eclipse.ui.IWorkbenchActionConstants;
|
||||
import org.eclipse.ui.progress.UIJob;
|
||||
|
||||
/**
|
||||
* Displays the list of executables gathered by the ExecutablesManager
|
||||
*/
|
||||
public class ExecutablesViewer extends BaseViewer implements IExecutablesChangeListener {
|
||||
|
||||
/**
|
||||
* Handles dropping executable files into the view
|
||||
*/
|
||||
public class ExecutablesDropAdapter extends ViewerDropAdapter {
|
||||
|
||||
protected ExecutablesDropAdapter(Viewer viewer) {
|
||||
super(viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performDrop(Object data) {
|
||||
final String[] fileNames = (String[]) data;
|
||||
ExecutablesViewer.this.getExecutablesView().importExecutables(fileNames);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateDrop(Object target, int operation, TransferData transferType) {
|
||||
return FileTransfer.getInstance().isSupportedType(transferType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public TreeColumn projectColumn;
|
||||
|
||||
public ExecutablesViewer(ExecutablesView executablesView, Composite parent, int style) {
|
||||
super(executablesView, parent, style);
|
||||
|
||||
// Setup D&D support
|
||||
int ops = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_DEFAULT;
|
||||
Transfer[] transfers = new Transfer[] { FileTransfer.getInstance() };
|
||||
ExecutablesDropAdapter adapter = new ExecutablesDropAdapter(this);
|
||||
adapter.setFeedbackEnabled(false);
|
||||
addDropSupport(ops | DND.DROP_DEFAULT, transfers, adapter);
|
||||
|
||||
// Setup content provider
|
||||
ExecutablesContentProvider exeContentProvider = new ExecutablesContentProvider(this);
|
||||
setContentProvider(exeContentProvider);
|
||||
setLabelProvider(exeContentProvider);
|
||||
|
||||
getTree().setHeaderVisible(true);
|
||||
getTree().setLinesVisible(true);
|
||||
executablesView.getSite().setSelectionProvider(this);
|
||||
|
||||
createColumns();
|
||||
initializeSorter();
|
||||
|
||||
setInput(ExecutablesManager.getExecutablesManager());
|
||||
|
||||
MenuManager popupMenuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
|
||||
IMenuListener listener = new IMenuListener() {
|
||||
public void menuAboutToShow(IMenuManager manager) {
|
||||
manager.add(ExecutablesViewer.this.getExecutablesView().refreshAction);
|
||||
manager.add(ExecutablesViewer.this.getExecutablesView().importAction);
|
||||
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
|
||||
}
|
||||
};
|
||||
popupMenuManager.addMenuListener(listener);
|
||||
popupMenuManager.setRemoveAllWhenShown(true);
|
||||
getExecutablesView().getSite().registerContextMenu(popupMenuManager, this.getExecutablesView().getSite().getSelectionProvider());
|
||||
Menu menu = popupMenuManager.createContextMenu(getTree());
|
||||
getTree().setMenu(menu);
|
||||
}
|
||||
|
||||
private void createColumns() {
|
||||
nameColumn = new TreeColumn(getTree(), SWT.NONE);
|
||||
nameColumn.setWidth(100);
|
||||
nameColumn.setText("Executable Name");
|
||||
nameColumn.setMoveable(true);
|
||||
nameColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.NAME));
|
||||
|
||||
projectColumn = new TreeColumn(getTree(), SWT.NONE);
|
||||
projectColumn.setWidth(100);
|
||||
projectColumn.setMoveable(true);
|
||||
projectColumn.setText("Project");
|
||||
projectColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.PROJECT));
|
||||
|
||||
locationColumn = new TreeColumn(getTree(), SWT.NONE);
|
||||
locationColumn.setWidth(100);
|
||||
locationColumn.setText("Location");
|
||||
locationColumn.setMoveable(true);
|
||||
locationColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.LOCATION));
|
||||
|
||||
sizeColumn = new TreeColumn(getTree(), SWT.NONE);
|
||||
sizeColumn.setWidth(100);
|
||||
sizeColumn.setText("Size");
|
||||
sizeColumn.setMoveable(true);
|
||||
sizeColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.SIZE));
|
||||
|
||||
modifiedColumn = new TreeColumn(getTree(), SWT.NONE);
|
||||
modifiedColumn.setWidth(100);
|
||||
modifiedColumn.setText("Modified");
|
||||
modifiedColumn.setMoveable(true);
|
||||
modifiedColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.MODIFIED));
|
||||
|
||||
typeColumn = new TreeColumn(getTree(), SWT.NONE);
|
||||
typeColumn.setWidth(100);
|
||||
typeColumn.setText("Type");
|
||||
typeColumn.setMoveable(true);
|
||||
typeColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.TYPE));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize column ordering and sorting
|
||||
*/
|
||||
private void initializeSorter() {
|
||||
byte orderType = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_TYPE_EXE).byteValue();
|
||||
switch (orderType) {
|
||||
case ExecutablesView.NAME:
|
||||
column_order[ExecutablesView.NAME] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_EXE).intValue();
|
||||
column_order[ExecutablesView.PROJECT] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.PROJECT:
|
||||
column_order[ExecutablesView.PROJECT] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_EXE).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.LOCATION:
|
||||
column_order[ExecutablesView.LOCATION] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_EXE).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.PROJECT] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.SIZE:
|
||||
column_order[ExecutablesView.SIZE] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_EXE).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.PROJECT] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.MODIFIED:
|
||||
column_order[ExecutablesView.MODIFIED] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_EXE).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.PROJECT] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
default:
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.PROJECT] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
}
|
||||
|
||||
ViewerComparator comparator = getViewerComparator(orderType);
|
||||
setComparator(comparator);
|
||||
if (orderType == ExecutablesView.NAME)
|
||||
setColumnSorting(nameColumn, column_order[ExecutablesView.NAME]);
|
||||
else if (orderType == ExecutablesView.PROJECT)
|
||||
setColumnSorting(projectColumn, column_order[ExecutablesView.PROJECT]);
|
||||
else if (orderType == ExecutablesView.LOCATION)
|
||||
setColumnSorting(locationColumn, column_order[ExecutablesView.LOCATION]);
|
||||
else if (orderType == ExecutablesView.SIZE)
|
||||
setColumnSorting(projectColumn, column_order[ExecutablesView.SIZE]);
|
||||
else if (orderType == ExecutablesView.MODIFIED)
|
||||
setColumnSorting(locationColumn, column_order[ExecutablesView.MODIFIED]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ViewerComparator getViewerComparator(int sortType) {
|
||||
if (sortType == ExecutablesView.PROJECT) {
|
||||
return new ExecutablesViewerComparator(sortType, column_order[ExecutablesView.PROJECT]) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(Viewer viewer, Object e1, Object e2) {
|
||||
Executable entry1 = (Executable) e1;
|
||||
Executable entry2 = (Executable) e2;
|
||||
return getComparator().compare(entry1.getProject().getName(), entry2.getProject().getName())
|
||||
* column_order[ExecutablesView.PROJECT];
|
||||
}
|
||||
};
|
||||
}
|
||||
return new ExecutablesViewerComparator(sortType, column_order[sortType]);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesChanged(org.eclipse.cdt.debug.core.executables.IExecutablesChangeEvent)
|
||||
*/
|
||||
public void executablesChanged(IExecutablesChangeEvent event) {
|
||||
// Executables have changed so refresh the view.
|
||||
final ExecutablesViewer viewer = this;
|
||||
UIJob refreshJob = new UIJob("Refresh Executables View") {
|
||||
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
viewer.refresh(null);
|
||||
viewer.packColumns();
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
refreshJob.schedule();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.jface.viewers.ColumnLabelProvider;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerComparator;
|
||||
|
||||
class ExecutablesViewerComparator extends ViewerComparator {
|
||||
|
||||
private int sortType;
|
||||
private int columnOrder;
|
||||
|
||||
public ExecutablesViewerComparator(int sortType, int columnOrder) {
|
||||
this.sortType = sortType;
|
||||
this.columnOrder = columnOrder;
|
||||
}
|
||||
|
||||
public int category(Object element) {
|
||||
if (element instanceof ITranslationUnit || element instanceof Executable)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(Viewer viewer, Object e1, Object e2) {
|
||||
|
||||
if (category(e1) == 1 && category(e2) == 1) {
|
||||
if (sortType == ExecutablesView.NAME) {
|
||||
String s1 = ((ColumnLabelProvider) ((TreeViewer) viewer).getLabelProvider()).getText(e1);
|
||||
String s2 = ((ColumnLabelProvider) ((TreeViewer) viewer).getLabelProvider()).getText(e2);
|
||||
return getComparator().compare(s1, s2) * columnOrder;
|
||||
}
|
||||
|
||||
if (sortType == ExecutablesView.SIZE) {
|
||||
long file1 = getFileSize(e1);
|
||||
long file2 = getFileSize(e2);
|
||||
return Long.valueOf(file1).compareTo(Long.valueOf(file2)) * columnOrder;
|
||||
}
|
||||
|
||||
if (sortType == ExecutablesView.LOCATION) {
|
||||
return getComparator().compare(getPath(e1).toOSString(), getPath(e2).toOSString()) * columnOrder;
|
||||
}
|
||||
|
||||
if (sortType == ExecutablesView.MODIFIED) {
|
||||
long file1 = getPath(e1).toFile().lastModified();
|
||||
long file2 = getPath(e2).toFile().lastModified();
|
||||
return Long.valueOf(file1).compareTo(Long.valueOf(file2)) * columnOrder;
|
||||
}
|
||||
|
||||
if (sortType == ExecutablesView.TYPE) {
|
||||
String ext1 = getPath(e1).getFileExtension();
|
||||
String s1 = ext1 != null ? ext1.toUpperCase() : "";
|
||||
String ext2 = getPath(e2).getFileExtension();
|
||||
String s2 = ext2 != null ? ext2.toUpperCase() : "";
|
||||
return getComparator().compare(s1, s2) * columnOrder;
|
||||
}
|
||||
}
|
||||
|
||||
return super.compare(viewer, e1, e2);
|
||||
}
|
||||
|
||||
private long getFileSize(Object element) {
|
||||
File file1 = getPath(element).toFile();
|
||||
if (file1.exists())
|
||||
return file1.length();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private IPath getPath(Object element) {
|
||||
if (element instanceof ITranslationUnit) {
|
||||
return ((ITranslationUnit) element).getPath();
|
||||
} else if (element instanceof Executable) {
|
||||
return ((Executable) element).getPath();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||
import org.eclipse.cdt.ui.CElementContentProvider;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
public class SourceFilesContentProvider extends CElementContentProvider {
|
||||
|
||||
public SourceFilesContentProvider(SourceFilesViewer viewer) {
|
||||
super(true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildren(Object element) {
|
||||
if (element instanceof ITranslationUnit) {
|
||||
IPath path = ((ITranslationUnit) element).getLocation();
|
||||
if (path != null && !path.toFile().exists())
|
||||
return false;
|
||||
}
|
||||
return super.hasChildren(element);
|
||||
}
|
||||
|
||||
public Object[] getElements(Object inputElement) {
|
||||
if (inputElement instanceof Executable) {
|
||||
Executable executable = (Executable) inputElement;
|
||||
ITranslationUnit[] sourceFiles = executable.getSourceFiles();
|
||||
if (sourceFiles.length == 0)
|
||||
return new String[] { "No source files found in " + executable.getName() };
|
||||
else
|
||||
return sourceFiles;
|
||||
}
|
||||
return new Object[] {};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||
import org.eclipse.cdt.ui.CElementLabelProvider;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.jface.resource.FontDescriptor;
|
||||
import org.eclipse.jface.resource.JFaceResources;
|
||||
import org.eclipse.jface.resource.LocalResourceManager;
|
||||
import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider;
|
||||
import org.eclipse.jface.viewers.ViewerCell;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
|
||||
|
||||
private SourceFilesViewer viewer;
|
||||
|
||||
private LocalResourceManager resourceManager = new LocalResourceManager(JFaceResources.getResources());
|
||||
|
||||
public SourceFilesLabelProvider(SourceFilesViewer viewer) {
|
||||
super(new CElementLabelProvider());
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(ViewerCell cell) {
|
||||
super.update(cell);
|
||||
|
||||
int orgColumnIndex = cell.getColumnIndex();
|
||||
|
||||
if (orgColumnIndex == 0) {
|
||||
if (cell.getElement() instanceof String) {
|
||||
cell.setText((String) cell.getElement());
|
||||
Font boldFont = resourceManager.createFont(FontDescriptor.createFrom(viewer.getTree().getFont()).setStyle(SWT.BOLD));
|
||||
cell.setFont(boldFont);
|
||||
}
|
||||
} else if (orgColumnIndex == 1) {
|
||||
cell.setText(null);
|
||||
if (cell.getElement() instanceof ITranslationUnit) {
|
||||
ITranslationUnit tu = (ITranslationUnit) cell.getElement();
|
||||
IPath path = tu.getLocation();
|
||||
if (path != null) {
|
||||
cell.setText(path.toOSString());
|
||||
if (path.toFile().exists())
|
||||
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
|
||||
else
|
||||
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
|
||||
}
|
||||
}
|
||||
cell.setImage(null);
|
||||
} else if (orgColumnIndex == 2) {
|
||||
cell.setText(null);
|
||||
if (cell.getElement() instanceof ITranslationUnit) {
|
||||
Executable executable = (Executable) viewer.getInput();
|
||||
Path path = new Path(executable.getOriginalLocation((ITranslationUnit) cell.getElement()));
|
||||
cell.setText(executable.getOriginalLocation((ITranslationUnit) cell.getElement()));
|
||||
if (path.toFile().exists())
|
||||
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
|
||||
else
|
||||
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
|
||||
}
|
||||
cell.setImage(null);
|
||||
} else if (orgColumnIndex == 3) {
|
||||
cell.setText(null);
|
||||
if (cell.getElement() instanceof ITranslationUnit) {
|
||||
ITranslationUnit tu = (ITranslationUnit) cell.getElement();
|
||||
IPath path = tu.getLocation();
|
||||
if (path != null && path.toFile().exists()) {
|
||||
long fileLength = path.toFile().length();
|
||||
cell.setText(Long.toString(fileLength));
|
||||
}
|
||||
}
|
||||
cell.setImage(null);
|
||||
} else if (orgColumnIndex == 4) {
|
||||
cell.setText(null);
|
||||
if (cell.getElement() instanceof ITranslationUnit) {
|
||||
ITranslationUnit tu = (ITranslationUnit) cell.getElement();
|
||||
IPath path = tu.getLocation();
|
||||
if (path != null && path.toFile().exists()) {
|
||||
long modified = path.toFile().lastModified();
|
||||
String dateTimeString = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(new Date(modified));
|
||||
cell.setText(dateTimeString);
|
||||
}
|
||||
}
|
||||
cell.setImage(null);
|
||||
} else if (orgColumnIndex == 5) {
|
||||
cell.setText(null);
|
||||
if (cell.getElement() instanceof ITranslationUnit) {
|
||||
ITranslationUnit tu = (ITranslationUnit) cell.getElement();
|
||||
IPath path = tu.getLocation();
|
||||
if (path != null) {
|
||||
String fileExtension = path.getFileExtension();
|
||||
if (fileExtension != null)
|
||||
cell.setText(fileExtension.toLowerCase());
|
||||
}
|
||||
}
|
||||
cell.setImage(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Nokia 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:
|
||||
* Nokia - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.ui.views.executables;
|
||||
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ISourceReference;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||
import org.eclipse.cdt.debug.core.executables.Executable;
|
||||
import org.eclipse.cdt.debug.internal.ui.sourcelookup.CSourceNotFoundEditorInput;
|
||||
import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
|
||||
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
|
||||
import org.eclipse.jface.viewers.IOpenListener;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.OpenEvent;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerComparator;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.DisposeEvent;
|
||||
import org.eclipse.swt.events.DisposeListener;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.swt.widgets.TreeColumn;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.progress.UIJob;
|
||||
|
||||
/**
|
||||
* Displays the list of source files for the executable selected in the
|
||||
* ExecutablesViewer.
|
||||
*/
|
||||
public class SourceFilesViewer extends BaseViewer implements ISourceLookupParticipant {
|
||||
|
||||
TreeColumn originalLocationColumn;
|
||||
private Tree sourceFilesTree;
|
||||
|
||||
public SourceFilesViewer(ExecutablesView view, Composite parent, int style) {
|
||||
super(view, parent, style);
|
||||
|
||||
setContentProvider(new SourceFilesContentProvider(this));
|
||||
setLabelProvider(new SourceFilesLabelProvider(this));
|
||||
sourceFilesTree = getTree();
|
||||
sourceFilesTree.setHeaderVisible(true);
|
||||
sourceFilesTree.setLinesVisible(true);
|
||||
|
||||
createColumns();
|
||||
|
||||
this.addOpenListener(new IOpenListener() {
|
||||
|
||||
public void open(OpenEvent event) {
|
||||
openSourceFile(event);
|
||||
}
|
||||
});
|
||||
|
||||
initializeSorter();
|
||||
|
||||
// We implement ISourceLookupParticipant so we can listen for changes to
|
||||
// source lookup as this viewer shows both original and remapped
|
||||
// locations
|
||||
CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().addParticipants(new ISourceLookupParticipant[] { this });
|
||||
sourceFilesTree.addDisposeListener(new DisposeListener() {
|
||||
|
||||
public void widgetDisposed(DisposeEvent e) {
|
||||
CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().removeParticipants(
|
||||
new ISourceLookupParticipant[] { SourceFilesViewer.this });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void openSourceFile(OpenEvent event) {
|
||||
boolean opened = false;
|
||||
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
|
||||
Object element = selection.getFirstElement();
|
||||
if (element instanceof ICElement) {
|
||||
if (element instanceof ITranslationUnit) {
|
||||
ITranslationUnit tu = (ITranslationUnit) element;
|
||||
IPath path = tu.getLocation();
|
||||
if (path != null && !path.toFile().exists()) {
|
||||
// Open the source not found editor
|
||||
IWorkbenchPage p = CUIPlugin.getActivePage();
|
||||
if (p != null) {
|
||||
try {
|
||||
String editorID = ICDebugUIConstants.CSOURCENOTFOUND_EDITOR_ID;
|
||||
p.openEditor(new CSourceNotFoundEditorInput(tu), editorID, true);
|
||||
opened = true;
|
||||
} catch (PartInitException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (!opened) {
|
||||
try {
|
||||
IEditorPart part = EditorUtility.openInEditor(element);
|
||||
if (part != null) {
|
||||
IWorkbenchPage page = getExecutablesView().getSite().getPage();
|
||||
page.bringToTop(part);
|
||||
if (element instanceof ISourceReference) {
|
||||
EditorUtility.revealInEditor(part, (ICElement) element);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createColumns() {
|
||||
nameColumn = new TreeColumn(sourceFilesTree, SWT.NONE);
|
||||
nameColumn.setWidth(100);
|
||||
nameColumn.setText("Source File Name");
|
||||
nameColumn.setMoveable(true);
|
||||
nameColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.NAME));
|
||||
|
||||
locationColumn = new TreeColumn(sourceFilesTree, SWT.NONE);
|
||||
locationColumn.setWidth(100);
|
||||
locationColumn.setText("Location");
|
||||
locationColumn.setMoveable(true);
|
||||
locationColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.LOCATION));
|
||||
|
||||
originalLocationColumn = new TreeColumn(sourceFilesTree, SWT.NONE);
|
||||
originalLocationColumn.setWidth(100);
|
||||
originalLocationColumn.setText("Original");
|
||||
originalLocationColumn.setMoveable(true);
|
||||
originalLocationColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.ORG_LOCATION));
|
||||
|
||||
sizeColumn = new TreeColumn(sourceFilesTree, SWT.NONE);
|
||||
sizeColumn.setWidth(100);
|
||||
sizeColumn.setText("Size");
|
||||
sizeColumn.setMoveable(true);
|
||||
sizeColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.SIZE));
|
||||
|
||||
modifiedColumn = new TreeColumn(sourceFilesTree, SWT.NONE);
|
||||
modifiedColumn.setWidth(100);
|
||||
modifiedColumn.setText("Modified");
|
||||
modifiedColumn.setMoveable(true);
|
||||
modifiedColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.MODIFIED));
|
||||
|
||||
typeColumn = new TreeColumn(sourceFilesTree, SWT.NONE);
|
||||
typeColumn.setWidth(100);
|
||||
typeColumn.setText("Type");
|
||||
typeColumn.setMoveable(true);
|
||||
typeColumn.addSelectionListener(new ColumnSelectionAdapter(ExecutablesView.TYPE));
|
||||
}
|
||||
|
||||
protected ViewerComparator getViewerComparator(int sortType) {
|
||||
if (sortType == ExecutablesView.ORG_LOCATION) {
|
||||
return new ExecutablesViewerComparator(sortType, column_order[ExecutablesView.ORG_LOCATION]) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(Viewer viewer, Object e1, Object e2) {
|
||||
if (e1 instanceof ITranslationUnit && e2 instanceof ITranslationUnit) {
|
||||
ITranslationUnit entry1 = (ITranslationUnit) e1;
|
||||
ITranslationUnit entry2 = (ITranslationUnit) e2;
|
||||
Executable exe = (Executable) getInput();
|
||||
String originalLocation1 = exe.getOriginalLocation(entry1);
|
||||
String originalLocation2 = exe.getOriginalLocation(entry2);
|
||||
return getComparator().compare(originalLocation1, originalLocation2) * column_order[ExecutablesView.ORG_LOCATION];
|
||||
}
|
||||
return super.compare(viewer, e1, e2);
|
||||
}
|
||||
};
|
||||
} else
|
||||
return new ExecutablesViewerComparator(sortType, column_order[sortType]);
|
||||
}
|
||||
|
||||
private void initializeSorter() {
|
||||
byte orderType = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_TYPE_SF).byteValue();
|
||||
switch (orderType) {
|
||||
case ExecutablesView.NAME:
|
||||
column_order[ExecutablesView.NAME] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_SF).intValue();
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.ORG_LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.LOCATION:
|
||||
column_order[ExecutablesView.LOCATION] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_SF).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.ORG_LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.ORG_LOCATION:
|
||||
column_order[ExecutablesView.ORG_LOCATION] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_SF).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.SIZE:
|
||||
column_order[ExecutablesView.SIZE] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_SF).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.ORG_LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
case ExecutablesView.MODIFIED:
|
||||
column_order[ExecutablesView.MODIFIED] = getExecutablesView().getMemento().getInteger(ExecutablesView.P_ORDER_VALUE_SF).intValue();
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.ORG_LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
break;
|
||||
default:
|
||||
column_order[ExecutablesView.MODIFIED] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.NAME] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.SIZE] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.ORG_LOCATION] = ExecutablesView.DESCENDING;
|
||||
column_order[ExecutablesView.TYPE] = ExecutablesView.DESCENDING;
|
||||
}
|
||||
|
||||
ViewerComparator comparator = getViewerComparator(orderType);
|
||||
setComparator(comparator);
|
||||
if (orderType == ExecutablesView.NAME)
|
||||
setColumnSorting(nameColumn, column_order[ExecutablesView.NAME]);
|
||||
else if (orderType == ExecutablesView.LOCATION)
|
||||
setColumnSorting(locationColumn, column_order[ExecutablesView.LOCATION]);
|
||||
else if (orderType == ExecutablesView.ORG_LOCATION)
|
||||
setColumnSorting(originalLocationColumn, column_order[ExecutablesView.ORG_LOCATION]);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
public Object[] findSourceElements(Object object) throws CoreException {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
public String getSourceName(Object object) throws CoreException {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void init(ISourceLookupDirector director) {
|
||||
}
|
||||
|
||||
public void sourceContainersChanged(ISourceLookupDirector director) {
|
||||
UIJob refreshJob = new UIJob("Refresh Source Files") {
|
||||
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
Object input = getInput();
|
||||
if (input != null && input instanceof Executable) {
|
||||
refresh(true);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
refreshJob.schedule();
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,12 @@ public interface ICDebugUIConstants {
|
|||
public static final String PLUGIN_ID = CDebugUIPlugin.getUniqueIdentifier();
|
||||
|
||||
public static final String PREFIX = PLUGIN_ID + "."; //$NON-NLS-1$
|
||||
|
||||
|
||||
/**
|
||||
* Executables view identifier (value <code>"org.eclipse.cdt.debug.ui.executablesView"</code>).
|
||||
*/
|
||||
public static final String ID_EXECUTABLES_VIEW = PREFIX + "executablesView"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Disassembly view identifier (value <code>"org.eclipse.cdt.debug.ui.DisassemblyView"</code>).
|
||||
*/
|
||||
|
|