Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/debug
diff options
context:
space:
mode:
authorKen Ryall2008-03-24 21:21:02 +0000
committerKen Ryall2008-03-24 21:21:02 +0000
commit3071e4834e349169773a86177381f2831e494b1d (patch)
treea0df77d9d498ed24d62d86c01f33c3a7f1a87475 /debug
parent2e3fbf6c23755e395ff5ba843f9e1b35279ab32e (diff)
downloadorg.eclipse.cdt-3071e4834e349169773a86177381f2831e494b1d.tar.gz
org.eclipse.cdt-3071e4834e349169773a86177381f2831e494b1d.tar.xz
org.eclipse.cdt-3071e4834e349169773a86177381f2831e494b1d.zip
Bug 182388, Executables view and supporting classes.
Diffstat (limited to 'debug')
-rw-r--r--debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF4
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java309
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesChangeEvent.java35
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java172
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableImporter.java19
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableProvider.java28
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeEvent.java19
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeListener.java20
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ISourceFileRemapping.java24
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableImporter.java210
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java166
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardSourceFileRemapping.java58
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java24
-rw-r--r--debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF1
-rw-r--r--debug/org.eclipse.cdt.debug.ui/icons/dlcl16/columns.gifbin0 -> 565 bytes
-rw-r--r--debug/org.eclipse.cdt.debug.ui/icons/dlcl16/import.gifbin0 -> 327 bytes
-rw-r--r--debug/org.eclipse.cdt.debug.ui/icons/dlcl16/refresh.gifbin0 -> 205 bytes
-rw-r--r--debug/org.eclipse.cdt.debug.ui/icons/elcl16/columns.gifbin0 -> 564 bytes
-rw-r--r--debug/org.eclipse.cdt.debug.ui/icons/elcl16/import.gifbin0 -> 327 bytes
-rw-r--r--debug/org.eclipse.cdt.debug.ui/icons/elcl16/refresh.gifbin0 -> 330 bytes
-rw-r--r--debug/org.eclipse.cdt.debug.ui/icons/obj16/exec_view_obj.gifbin0 -> 378 bytes
-rw-r--r--debug/org.eclipse.cdt.debug.ui/plugin.properties1
-rw-r--r--debug/org.eclipse.cdt.debug.ui/plugin.xml15
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/BaseViewer.java84
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesContentProvider.java139
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java500
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewer.java251
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewerComparator.java93
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java47
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java118
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java276
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/ICDebugUIConstants.java7
32 files changed, 2611 insertions, 9 deletions
diff --git a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
index 62f3ed6be9b..0b9c5f5322e 100644
--- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
+++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
@@ -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
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java
new file mode 100644
index 00000000000..688d9101b30
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java
@@ -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;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesChangeEvent.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesChangeEvent.java
new file mode 100644
index 00000000000..60bd74ce9d5
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesChangeEvent.java
@@ -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;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java
new file mode 100644
index 00000000000..c50e3f5b14a
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java
@@ -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;
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableImporter.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableImporter.java
new file mode 100644
index 00000000000..8fe0ef324ce
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableImporter.java
@@ -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);
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableProvider.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableProvider.java
new file mode 100644
index 00000000000..6c4ede78d09
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutableProvider.java
@@ -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);
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeEvent.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeEvent.java
new file mode 100644
index 00000000000..3c559eadae4
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeEvent.java
@@ -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();
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeListener.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeListener.java
new file mode 100644
index 00000000000..bfa0677655f
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/IExecutablesChangeListener.java
@@ -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);
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ISourceFileRemapping.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ISourceFileRemapping.java
new file mode 100644
index 00000000000..85948e3b61a
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ISourceFileRemapping.java
@@ -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);
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableImporter.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableImporter.java
new file mode 100644
index 00000000000..3d9a20729d0
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableImporter.java
@@ -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;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java
new file mode 100644
index 00000000000..cdb81086350
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java
@@ -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;
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardSourceFileRemapping.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardSourceFileRemapping.java
new file mode 100644
index 00000000000..001dd717dde
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardSourceFileRemapping.java
@@ -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;
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java
index 4e99c16951f..38dead7aa3a 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/AbsolutePathSourceContainer.java
@@ -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
diff --git a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF
index d912ffb4090..87f0bd6ea89 100644
--- a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF
+++ b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF
@@ -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,
diff --git a/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/columns.gif b/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/columns.gif
new file mode 100644
index 00000000000..9328079cf9c
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/columns.gif
Binary files differ
diff --git a/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/import.gif b/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/import.gif
new file mode 100644
index 00000000000..d38085ad9c2
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/import.gif
Binary files differ
diff --git a/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/refresh.gif b/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/refresh.gif
new file mode 100644
index 00000000000..6eafa48cfb0
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/icons/dlcl16/refresh.gif
Binary files differ
diff --git a/debug/org.eclipse.cdt.debug.ui/icons/elcl16/columns.gif b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/columns.gif
new file mode 100644
index 00000000000..e5e5263eb46
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/columns.gif
Binary files differ
diff --git a/debug/org.eclipse.cdt.debug.ui/icons/elcl16/import.gif b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/import.gif
new file mode 100644
index 00000000000..d38085ad9c2
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/import.gif
Binary files differ
diff --git a/debug/org.eclipse.cdt.debug.ui/icons/elcl16/refresh.gif b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/refresh.gif
new file mode 100644
index 00000000000..e3831471a65
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/icons/elcl16/refresh.gif
Binary files differ
diff --git a/debug/org.eclipse.cdt.debug.ui/icons/obj16/exec_view_obj.gif b/debug/org.eclipse.cdt.debug.ui/icons/obj16/exec_view_obj.gif
new file mode 100644
index 00000000000..d5f502a9746
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/icons/obj16/exec_view_obj.gif
Binary files differ
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties
index dc1a1876dec..62dfebaa642 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.properties
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties
@@ -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
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml
index 5e775e60491..adb67e005f9 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.xml
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml
@@ -17,6 +17,13 @@
<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"
category="org.eclipse.debug.ui"
@@ -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>
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/BaseViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/BaseViewer.java
new file mode 100644
index 00000000000..69df1bc481a
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/BaseViewer.java
@@ -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);
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesContentProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesContentProvider.java
new file mode 100644
index 00000000000..67a28e1c979
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesContentProvider.java
@@ -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[] {};
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java
new file mode 100644
index 00000000000..5382fefa415
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java
@@ -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;
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewer.java
new file mode 100644
index 00000000000..631385f844e
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewer.java
@@ -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();
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewerComparator.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewerComparator.java
new file mode 100644
index 00000000000..78049171fd1
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesViewerComparator.java
@@ -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;
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java
new file mode 100644
index 00000000000..e69e02759a8
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java
@@ -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[] {};
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java
new file mode 100644
index 00000000000..d813154c0ed
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java
@@ -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);
+ }
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java
new file mode 100644
index 00000000000..a3ecf577afa
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java
@@ -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();
+ }
+
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/ICDebugUIConstants.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/ICDebugUIConstants.java
index 727beb01cbf..b9324194a81 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/ICDebugUIConstants.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/ICDebugUIConstants.java
@@ -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>).
*/

Back to the top