Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2008-09-25 21:36:25 +0000
committereutarass2008-09-25 21:36:25 +0000
commitc6d9344ab3988164cf6008d45fc80f83036a5f51 (patch)
treedfa526ecb45363f3f7cd3df4dcab43ce41ee5a34
parenta3e68f01b6d211fc5832e695037a562a7a65af2d (diff)
downloadorg.eclipse.tcf-c6d9344ab3988164cf6008d45fc80f83036a5f51.tar.gz
org.eclipse.tcf-c6d9344ab3988164cf6008d45fc80f83036a5f51.tar.xz
org.eclipse.tcf-c6d9344ab3988164cf6008d45fc80f83036a5f51.zip
New extension point: org.eclipse.tm.tcf.debug.ui.launch.context - for integration with development tools.
New plug-in: org.eclipse.tm.tcf.cdt.ui - contains TCF/CDT integration code. TCF Launch Configuration is improved: now supports: default values from current CDT project, search of executable files in CDT projects, download of executable file to remote target.
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/.classpath7
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/.project28
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.core.prefs18
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.ui.prefs4
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/META-INF/MANIFEST.MF19
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/about.html28
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/build.properties9
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties12
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml9
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java76
-rw-r--r--plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFLaunchContext.java326
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/icons/target_tab.gifbin0 -> 567 bytes
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/schema/launch_context.exsd72
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java14
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/ITCFLaunchContext.java79
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java57
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java1079
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTabGroup.java1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java801
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java53
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFLaunchDelegate.java10
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java153
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/launch/LaunchDialogTabGroup.java4
26 files changed, 2072 insertions, 792 deletions
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/.classpath b/plugins/org.eclipse.tm.tcf.cdt.ui/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/.project b/plugins/org.eclipse.tm.tcf.cdt.ui/.project
new file mode 100644
index 000000000..5cbeef203
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.tcf.cdt.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..e115508c0
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,18 @@
+#Mon Sep 22 12:28:22 PDT 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,.svn/
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..547f1a097
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,4 @@
+#Tue Sep 23 17:25:53 PDT 2008
+eclipse.preferences.version=1
+formatter_profile=_Java STD
+formatter_settings_version=11
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.tm.tcf.cdt.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..6837b4167
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.tcf.cdt.ui;singleton:=true
+Bundle-Version: 0.2.0
+Bundle-Activator: org.eclipse.tm.internal.tcf.cdt.ui.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.debug.core,
+ org.eclipse.cdt.core,
+ org.eclipse.core.resources,
+ org.eclipse.cdt.debug.core,
+ org.eclipse.debug.ui,
+ org.eclipse.cdt.ui,
+ org.eclipse.tm.tcf.debug,
+ org.eclipse.tm.tcf.debug.ui
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-Vendor: %providerName
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/about.html b/plugins/org.eclipse.tm.tcf.cdt.ui/about.html
new file mode 100644
index 000000000..6c5b3615b
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>January 10, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/build.properties b/plugins/org.eclipse.tm.tcf.cdt.ui/build.properties
new file mode 100644
index 000000000..43883590f
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ plugin.properties
+src.includes = about.html
+ \ No newline at end of file
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties
new file mode 100644
index 000000000..c4fbf4d03
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Wind River Systems - initial implementation
+###############################################################################
+pluginName=TCF/CDT Integration UI (Incubation)
+providerName=Eclipse.org
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml
new file mode 100644
index 000000000..3871f04ea
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+
+ <extension point="org.eclipse.tm.tcf.debug.ui.launch_context">
+ <class name="org.eclipse.tm.internal.tcf.cdt.ui.TCFLaunchContext" />
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java
new file mode 100644
index 000000000..9a5060fcd
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/Activator.java
@@ -0,0 +1,76 @@
+package org.eclipse.tm.internal.tcf.cdt.ui;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ public static final String PLUGIN_ID = "org.eclipse.tm.tcf.cdt.ui";
+ private static Activator plugin;
+
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+
+ public static void log(Throwable e) {
+ log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
+ }
+
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ return getDefault().getWorkbench().getActiveWorkbenchWindow();
+ }
+
+ public static IWorkbenchPage getActivePage() {
+ IWorkbenchWindow w = getActiveWorkbenchWindow();
+ if (w != null) {
+ return w.getActivePage();
+ }
+ return null;
+ }
+
+ public static Shell getActiveWorkbenchShell() {
+ IWorkbenchWindow window = getActiveWorkbenchWindow();
+ if (window != null) {
+ return window.getShell();
+ }
+ return null;
+ }
+
+ public static void errorDialog(String message, IStatus status) {
+ log(status);
+ Shell shell = getActiveWorkbenchShell();
+ if (shell == null) return;
+ ErrorDialog.openError(shell, "Error", message, status);
+ }
+
+ public static void errorDialog(String message, Throwable t) {
+ log(t);
+ Shell shell = getActiveWorkbenchShell();
+ if (shell == null) return;
+ IStatus status = new Status(IStatus.ERROR, PLUGIN_ID, 1, t.getMessage(), null);
+ ErrorDialog.openError(shell, "Error", message, status);
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFLaunchContext.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFLaunchContext.java
new file mode 100644
index 000000000..83c5fb75a
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFLaunchContext.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.cdt.ui;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.IBinaryParser;
+import org.eclipse.cdt.core.ICExtensionReference;
+import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IBinary;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
+import org.eclipse.cdt.ui.CElementLabelProvider;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.ui.launch.ITCFLaunchContext;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.dialogs.TwoPaneElementSelector;
+
+public class TCFLaunchContext implements ITCFLaunchContext {
+
+ public boolean isActive() {
+ return getContext(null) != null;
+ }
+
+ public boolean isSupportedProject(IProject project) {
+ return CoreModel.getDefault().getCModel().getCProject(project.getName()) != null;
+ }
+
+ public void setDefaults(ILaunchConfigurationDialog dlg, ILaunchConfigurationWorkingCopy config) {
+ ICElement cElement = getContext(config);
+ if (cElement != null) {
+ initializeCProject(cElement, config);
+ initializeProgramName(cElement, dlg, config);
+ }
+ }
+
+ /**
+ * Returns the current C element context from which to initialize default
+ * settings, or <code>null</code> if none. Note, if possible we will
+ * return the IBinary based on configuration entry as this may be more useful then
+ * just the project.
+ *
+ * @return C element context.
+ */
+ private ICElement getContext(ILaunchConfiguration config) {
+ String projectName = null;
+ String programName = null;
+ if (config != null) {
+ try {
+ projectName = config.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, (String)null);
+ programName = config.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, (String)null);
+ }
+ catch (CoreException e) {
+ Activator.log(e);
+ }
+ }
+ Object obj = null;
+ IWorkbenchPage page = Activator.getActivePage();
+ if (projectName != null && !projectName.equals("")) { //$NON-NLS-1$
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ ICProject cProject = CCorePlugin.getDefault().getCoreModel().create(project);
+ if (cProject != null && cProject.exists()) obj = cProject;
+ }
+ else {
+ if (page != null) {
+ ISelection selection = page.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection)selection;
+ if (!ss.isEmpty()) obj = ss.getFirstElement();
+ }
+ }
+ }
+ if (obj instanceof IResource) {
+ ICElement ce = CoreModel.getDefault().create((IResource)obj);
+ if (ce == null) {
+ IProject pro = ((IResource)obj).getProject();
+ ce = CoreModel.getDefault().create(pro);
+ }
+ obj = ce;
+ }
+ if (obj instanceof ICElement) {
+ if (programName == null || programName.equals("")) { //$NON-NLS-1$
+ return (ICElement)obj;
+ }
+ ICElement ce = (ICElement)obj;
+ IProject project;
+ project = (IProject)ce.getCProject().getResource();
+ IPath programFile = project.getFile(programName).getLocation();
+ ce = CCorePlugin.getDefault().getCoreModel().create(programFile);
+ if (ce != null && ce.exists()) return ce;
+ return (ICElement)obj;
+ }
+ IEditorPart part = page.getActiveEditor();
+ if (part != null) {
+ IEditorInput input = part.getEditorInput();
+ return (ICElement)input.getAdapter(ICElement.class);
+ }
+ return null;
+ }
+
+ /**
+ * Set the C project attribute based on the ICElement.
+ */
+ private void initializeCProject(ICElement cElement, ILaunchConfigurationWorkingCopy config) {
+ ICProject cProject = cElement.getCProject();
+ String name = null;
+ if (cProject != null && cProject.exists()) {
+ name = cProject.getElementName();
+ config.setMappedResources(new IResource[] {cProject.getProject()});
+ }
+ config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, name);
+ }
+
+ /**
+ * Set the program name attributes on the working copy based on the ICElement
+ */
+ private void initializeProgramName(ICElement cElement, ILaunchConfigurationDialog dlg, ILaunchConfigurationWorkingCopy config) {
+
+ boolean renamed = false;
+
+ if (!(cElement instanceof IBinary)) {
+ cElement = cElement.getCProject();
+ }
+
+ if (cElement instanceof ICProject) {
+
+ IProject project = cElement.getCProject().getProject();
+ String name = project.getName();
+ ICProjectDescription projDes = CCorePlugin.getDefault().getProjectDescription(project);
+ if (projDes != null) {
+ String buildConfigName = projDes.getActiveConfiguration().getName();
+ name = name + " " + buildConfigName; //$NON-NLS-1$
+ }
+ name = dlg.generateName(name);
+ config.rename(name);
+ renamed = true;
+ }
+
+ IBinary binary = null;
+ if (cElement instanceof ICProject) {
+ IBinary[] bins = getBinaryFiles((ICProject)cElement);
+ if (bins != null && bins.length == 1) {
+ binary = bins[0];
+ }
+ }
+ else if (cElement instanceof IBinary) {
+ binary = (IBinary)cElement;
+ }
+
+ if (binary != null) {
+ String path;
+ path = binary.getResource().getProjectRelativePath().toOSString();
+ config.setAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, path);
+ if (!renamed)
+ {
+ String name = binary.getElementName();
+ int index = name.lastIndexOf('.');
+ if (index > 0) {
+ name = name.substring(0, index);
+ }
+ name = dlg.generateName(name);
+ config.rename(name);
+ renamed = true;
+ }
+ }
+
+ if (!renamed) {
+ String name = dlg.generateName(cElement.getCProject().getElementName());
+ config.rename(name);
+ }
+ }
+
+ public String getBuildConfigID(IProject project) {
+ ICProjectDescription projDes = CCorePlugin.getDefault().getProjectDescription(project);
+ if (projDes == null) return null;
+ return projDes.getActiveConfiguration().getId();
+ }
+
+ /**
+ * Iterate through and suck up all of the executable files that we can find.
+ */
+ private IBinary[] getBinaryFiles(final ICProject cproject) {
+ if (cproject == null || !cproject.exists()) return null;
+ final Display display = Display.getCurrent();
+ final Object[] ret = new Object[1];
+ BusyIndicator.showWhile(display, new Runnable() {
+
+ public void run() {
+ try {
+ ret[0] = cproject.getBinaryContainer().getBinaries();
+ }
+ catch (CModelException e) {
+ Activator.errorDialog("Launch UI internal error", e);
+ }
+ }
+ });
+ return (IBinary[])ret[0];
+ }
+
+ /**
+ * Return true if given file path names a binary file.
+ * @param project
+ * @param exePath
+ * @return true if binary file.
+ * @throws CoreException
+ */
+ public boolean isBinary(IProject project, IPath exePath) throws CoreException {
+ ICExtensionReference[] parserRef = CCorePlugin.getDefault().getBinaryParserExtensions(project);
+ for (int i = 0; i < parserRef.length; i++) {
+ try {
+ IBinaryParser parser = (IBinaryParser)parserRef[i].createExtension();
+ if ((IBinaryObject)parser.getBinary(exePath) != null) return true;
+ }
+ catch (Exception e) {
+ }
+ }
+ IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser();
+ try {
+ return (IBinaryObject)parser.getBinary(exePath) != null;
+ }
+ catch (Exception e) {
+ }
+ return false;
+ }
+
+ public String chooseBinary(Shell shell, IProject project) {
+ ILabelProvider programLabelProvider = new CElementLabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof IBinary) {
+ IBinary bin = (IBinary)element;
+ StringBuffer name = new StringBuffer();
+ name.append(bin.getPath().lastSegment());
+ return name.toString();
+ }
+ return super.getText(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (! (element instanceof ICElement)) {
+ return super.getImage(element);
+ }
+ ICElement celement = (ICElement)element;
+
+ if (celement.getElementType() == ICElement.C_BINARY) {
+ IBinary belement = (IBinary)celement;
+ if (belement.isExecutable()) {
+ return DebugUITools.getImage(IDebugUIConstants.IMG_ACT_RUN);
+ }
+ }
+
+ return super.getImage(element);
+ }
+ };
+
+ ILabelProvider qualifierLabelProvider = new CElementLabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof IBinary) {
+ IBinary bin = (IBinary)element;
+ StringBuffer name = new StringBuffer();
+ name.append(bin.getCPU() + (bin.isLittleEndian() ? "le" : "be")); //$NON-NLS-1$ //$NON-NLS-2$
+ name.append(" - "); //$NON-NLS-1$
+ name.append(bin.getPath().toString());
+ return name.toString();
+ }
+ return super.getText(element);
+ }
+ };
+
+ TwoPaneElementSelector dialog = new TwoPaneElementSelector(shell, programLabelProvider, qualifierLabelProvider);
+ dialog.setElements(getBinaryFiles(getCProject(project.getName())));
+ dialog.setMessage("Choose program to run");
+ dialog.setTitle("Program Selection");
+ dialog.setUpperListLabel("Binaries:");
+ dialog.setLowerListLabel("Qualifier:");
+ dialog.setMultipleSelection(false);
+ // dialog.set
+ if (dialog.open() != Window.OK) return null;
+ IBinary binary = (IBinary)dialog.getFirstResult();
+ return binary.getResource().getProjectRelativePath().toString();
+ }
+
+ /**
+ * Return the ICProject corresponding to the project name in the project name text field, or
+ * null if the text does not match a project name.
+ */
+ private ICProject getCProject(String name) {
+ String projectName = name.trim();
+ if (projectName.length() < 1) return null;
+ return CoreModel.getDefault().getCModel().getCProject(projectName);
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/icons/target_tab.gif b/plugins/org.eclipse.tm.tcf.debug.ui/icons/target_tab.gif
new file mode 100644
index 000000000..e9df7b871
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/icons/target_tab.gif
Binary files differ
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
index b593b7cfe..6b3a641af 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
@@ -2,6 +2,8 @@
<?eclipse version="3.2"?>
<plugin>
+ <extension-point id="launch_context" name="TCF Launch Context" schema="schema/launch_context.exsd"/>
+
<extension point="org.eclipse.tm.tcf.startup"/>
<extension
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/schema/launch_context.exsd b/plugins/org.eclipse.tm.tcf.debug.ui/schema/launch_context.exsd
new file mode 100644
index 000000000..473255026
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/schema/launch_context.exsd
@@ -0,0 +1,72 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.tcf">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.tm.tcf.debug.ui" id="launch_context" name="TCF Launch Context"/>
+ </appInfo>
+ <documentation>
+ This extension point is used to register plugins
+ that want to extends TCF Launch Configuration functionality.
+ </documentation>
+
+</annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="class" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="class">
+ <complexType>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ Class should implement ILaunchContext interface
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
index 55817ebd0..275f9c113 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
@@ -126,4 +126,18 @@ public class Activator extends AbstractUIPlugin {
plugin.getBundle().getSymbolicName(), IStatus.OK, msg, err));
}
}
+
+ /**
+ * Send error message into Eclipse log.
+ * @param err - exception
+ */
+ public static void log(Throwable err) {
+ if (plugin == null || plugin.getLog() == null) {
+ err.printStackTrace();
+ }
+ else {
+ plugin.getLog().log(new Status(IStatus.ERROR,
+ plugin.getBundle().getSymbolicName(), IStatus.OK, "Unhandled exception in TCF UI", err));
+ }
+ }
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java
index 30629136c..285932265 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java
@@ -25,6 +25,7 @@ public class ImageCache {
public static final String
IMG_TCF = "icons/tcf.gif",
+ IMG_TARGET_TAB = "icons/target_tab.gif",
IMG_ARGUMENTS_TAB = "icons/arguments_tab.gif",
IMG_ATTRIBUTE = "icons/attribute.gif",
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/ITCFLaunchContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/ITCFLaunchContext.java
new file mode 100644
index 000000000..90be235bc
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/ITCFLaunchContext.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * TCF clients can implement ITCFLaunchContext to provide information about
+ * workspace projects to TCF Launch Configuration.
+ *
+ * The information includes default values for launch configuration attributes,
+ * list of executable binary files, etc.
+ *
+ * Since each project type can have its own methods to retrieve relevant information,
+ * there should be implementation of this interface for each project type that support TCF.
+ *
+ * Implementation should be able to examine current IDE state (like active editor input source,
+ * project explorer selection, etc.) and figure out an "active project".
+ */
+public interface ITCFLaunchContext {
+
+ /**
+ * Check if this context is currently active.
+ * @return true if active.
+ */
+ boolean isActive();
+
+ /**
+ * Check if this context recognizes type of a project.
+ * @param project
+ * @return true if the project is supported by this context.
+ */
+ boolean isSupportedProject(IProject project);
+
+ /**
+ * Set launch configuration attributes to default values best suited for current context.
+ * @param dlg - currently open launch configuration dialog
+ * @param config - currently open launch configuration
+ */
+ void setDefaults(ILaunchConfigurationDialog dlg, ILaunchConfigurationWorkingCopy config);
+
+ /**
+ * Get project build configuration ID.
+ * @param project
+ * @return build configuration ID.
+ */
+ String getBuildConfigID(IProject project);
+
+ /**
+ * Show a dialog box that allows user to select executable binary file from a list
+ * of available file in this context.
+ * @param project_name
+ * @param shell
+ * @return binary file path
+ */
+ String chooseBinary(Shell shell, IProject project);
+
+ /**
+ * Check if a path represents an executable binary file.
+ * @param project
+ * @param path
+ * @return
+ * @throws CoreException
+ */
+ boolean isBinary(IProject project, IPath path) throws CoreException;
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java
index 23c43051b..c13c7b310 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFArgumentsTab.java
@@ -26,7 +26,7 @@ import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
@@ -36,8 +36,6 @@ public class TCFArgumentsTab extends AbstractLaunchConfigurationTab {
private Text text_arguments;
private Button button_variables;
- private Text text_working_dir;
- private Button button_default_dir;
public void createControl(Composite parent) {
Font font = parent.getFont();
@@ -51,30 +49,34 @@ public class TCFArgumentsTab extends AbstractLaunchConfigurationTab {
setControl(comp);
createArgumentsGroup(comp);
- createWorkingDirGroup(comp);
}
- private void createArgumentsGroup(Composite comp) {
- Font font = comp.getFont();
+ private void createArgumentsGroup(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(gd);
- Group group = new Group(comp, SWT.NONE);
- group.setFont(font);
- group.setLayout(new GridLayout());
- group.setLayoutData(new GridData(GridData.FILL_BOTH));
- group.setText("Program Arguments");
+ Label label = new Label(comp, SWT.NONE);
+ label.setText("Program Arguments:");
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ label.setLayoutData(gd);
- text_arguments = new Text(group, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
- GridData gd = new GridData(GridData.FILL_BOTH);
+ text_arguments = new Text(comp, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
+ gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 40;
gd.widthHint = 100;
text_arguments.setLayoutData(gd);
- text_arguments.setFont(font);
text_arguments.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent evt) {
updateLaunchConfigurationDialog();
}
});
- button_variables= createPushButton(group, "Variables", null);
+ button_variables= createPushButton(comp, "Variables", null);
gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
button_variables.setLayoutData(gd);
button_variables.addSelectionListener(new SelectionAdapter() {
@@ -84,27 +86,6 @@ public class TCFArgumentsTab extends AbstractLaunchConfigurationTab {
});
}
- private void createWorkingDirGroup(Composite comp) {
- Font font = comp.getFont();
-
- Group group = new Group(comp, SWT.NONE);
- GridLayout workingDirLayout = new GridLayout();
- workingDirLayout.makeColumnsEqualWidth = false;
- group.setLayout(workingDirLayout);
- group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- group.setFont(font);
- group.setText("Working directory");
-
- text_working_dir = new Text(group, SWT.SINGLE | SWT.BORDER);
- text_working_dir.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- text_working_dir.setFont(font);
-
- button_default_dir = new Button(group, SWT.CHECK);
- button_default_dir.setText("Use default");
- button_default_dir.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
- button_default_dir.setFont(font);
- }
-
/**
* A variable entry button has been pressed for the given text
* field. Prompt the user for a variable and enter the result
@@ -137,7 +118,6 @@ public class TCFArgumentsTab extends AbstractLaunchConfigurationTab {
public void initializeFrom(ILaunchConfiguration configuration) {
try {
text_arguments.setText(configuration.getAttribute(TCFLaunchDelegate.ATTR_PROGRAM_ARGUMENTS, "")); //$NON-NLS-1$
- text_working_dir.setText(configuration.getAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, "")); //$NON-NLS-1$
}
catch (CoreException e) {
setErrorMessage("Cannot read launch configuration: " + e);
@@ -148,9 +128,6 @@ public class TCFArgumentsTab extends AbstractLaunchConfigurationTab {
configuration.setAttribute(
TCFLaunchDelegate.ATTR_PROGRAM_ARGUMENTS,
getAttributeValueFrom(text_arguments));
- configuration.setAttribute(
- TCFLaunchDelegate.ATTR_WORKING_DIRECTORY,
- getAttributeValueFrom(text_working_dir));
}
protected String getAttributeValueFrom(Text text) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
index 798b0bbde..d9402707d 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,821 +10,482 @@
*******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui.launch;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
+import java.io.File;
+import org.eclipse.core.resources.IProject;
+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.Path;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.ProgressBar;
-import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
-import org.eclipse.tm.internal.tcf.debug.launch.TCFUserDefPeer;
-import org.eclipse.tm.internal.tcf.debug.tests.TCFTestSuite;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
-import org.eclipse.tm.tcf.protocol.IChannel;
-import org.eclipse.tm.tcf.protocol.IPeer;
-import org.eclipse.tm.tcf.protocol.Protocol;
-import org.eclipse.tm.tcf.protocol.IChannel.IChannelListener;
-import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+import org.osgi.framework.Bundle;
-
-/**
- * Launch configuration dialog tab to specify the Target Communication Framework
- * configuration.
- */
public class TCFMainTab extends AbstractLaunchConfigurationTab {
-
- private Text peer_id_text;
- private Text program_text;
- private Tree peer_tree;
- private Runnable update_peer_buttons;
- private final PeerInfo peer_info = new PeerInfo();
- private Display display;
-
- private final Map<LocatorListener,ILocator> listeners = new HashMap<LocatorListener,ILocator>();
-
- private static class PeerInfo {
- PeerInfo parent;
- int index;
- String id;
- Map<String,String> attrs;
- PeerInfo[] children;
- boolean children_pending;
- Throwable children_error;
- IPeer peer;
- }
-
- private class LocatorListener implements ILocator.LocatorListener {
-
- private final PeerInfo parent;
-
- LocatorListener(PeerInfo parent) {
- this.parent = parent;
- }
-
- public void peerAdded(final IPeer peer) {
- if (display == null) return;
- final String id = peer.getID();
- final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- PeerInfo[] buf = new PeerInfo[arr.length + 1];
- System.arraycopy(arr, 0, buf, 0, arr.length);
- PeerInfo info = new PeerInfo();
- info.parent = parent;
- info.index = arr.length;
- info.id = id;
- info.attrs = attrs;
- info.peer = peer;
- buf[arr.length] = info;
- parent.children = buf;
- updateItems(parent);
- }
- });
- }
-
- public void peerChanged(final IPeer peer) {
- if (display == null) return;
- final String id = peer.getID();
- final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- for (int i = 0; i < arr.length; i++) {
- if (arr[i].id.equals(id)) {
- arr[i].attrs = attrs;
- arr[i].peer = peer;
- loadChildren(arr[i]);
- updateItems(parent);
- }
- }
- }
- });
- }
- public void peerRemoved(final String id) {
- if (display == null) return;
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- PeerInfo[] buf = new PeerInfo[arr.length - 1];
- int j = 0;
- for (int i = 0; i < arr.length; i++) {
- if (!arr[i].id.equals(id)) {
- buf[j++] = arr[i];
- }
- }
- parent.children = buf;
- updateItems(parent);
- }
- });
- }
+ private Text project_text;
+ private Text local_program_text;
+ private Text remote_program_text;
+ private Text working_dir_text;
+ private Button default_dir_button;
+ private Button terminal_button;
- public void peerHeartBeat(final String id) {
- if (display == null) return;
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- for (int i = 0; i < arr.length; i++) {
- if (arr[i].id.equals(id)) {
- if (arr[i].children_error != null) {
- loadChildren(arr[i]);
- }
- break;
- }
- }
- }
- });
- }
- }
-
public void createControl(Composite parent) {
- display = parent.getDisplay();
- assert display != null;
-
- Font font = parent.getFont();
Composite comp = new Composite(parent, SWT.NONE);
- GridLayout layout = new GridLayout(1, true);
- comp.setLayout(layout);
- comp.setFont(font);
-
- GridData gd = new GridData(GridData.FILL_BOTH);
- comp.setLayoutData(gd);
setControl(comp);
- createTargetGroup(comp);
- createProgramGroup(comp);
+ GridLayout topLayout = new GridLayout();
+ comp.setLayout(topLayout);
+
+ createVerticalSpacer(comp, 1);
+ createProjectGroup(comp);
+ createApplicationGroup(comp);
+ createWorkingDirGroup(comp);
+ createVerticalSpacer(comp, 1);
+ createTerminalOption(comp, 1);
}
- private void createTargetGroup(Composite parent) {
- Font font = parent.getFont();
-
+ private void createProjectGroup(Composite parent) {
Group group = new Group(parent, SWT.NONE);
- GridLayout top_layout = new GridLayout();
- top_layout.verticalSpacing = 0;
- top_layout.numColumns = 2;
- group.setLayout(top_layout);
- group.setLayoutData(new GridData(GridData.FILL_BOTH));
- group.setFont(font);
- group.setText("Target");
-
- createVerticalSpacer(group, top_layout.numColumns);
-
- Label host_label = new Label(group, SWT.NONE);
- host_label.setText("Target ID:");
- host_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
- host_label.setFont(font);
-
- peer_id_text = new Text(group, SWT.SINGLE | SWT.BORDER);
- peer_id_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- peer_id_text.setFont(font);
- peer_id_text.setEditable(false);
- peer_id_text.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent e) {
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setText("Project");
+
+ Label label = new Label(group, SWT.NONE);
+ label.setText("Project Name:");
+ GridData gd = new GridData();
+ gd.horizontalSpan = 2;
+ label.setLayoutData(gd);
+
+ project_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ project_text.setLayoutData(gd);
+ project_text.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent evt) {
updateLaunchConfigurationDialog();
}
});
- createVerticalSpacer(group, top_layout.numColumns);
+ Button project_button = createPushButton(group, "Browse...", null);
+ project_button.addSelectionListener(new SelectionAdapter() {
- Label peer_label = new Label(group, SWT.NONE);
- peer_label.setText("&Available targets:");
- peer_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
- peer_label.setFont(font);
-
- loadChildren(peer_info);
- createPeerListArea(group);
- }
-
- private void createPeerListArea(Composite parent) {
- Font font = parent.getFont();
- Composite composite = new Composite(parent, SWT.NONE);
- GridLayout layout = new GridLayout(2, false);
- composite.setFont(font);
- composite.setLayout(layout);
- composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
-
- peer_tree = new Tree(composite, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE);
- GridData gd = new GridData(GridData.FILL_BOTH);
- gd.minimumHeight = 150;
- gd.minimumWidth = 470;
- peer_tree.setLayoutData(gd);
-
- for (int i = 0; i < 5; i++) {
- TreeColumn column = new TreeColumn(peer_tree, SWT.LEAD, i);
- column.setMoveable(true);
- switch (i) {
- case 0:
- column.setText("Name");
- column.setWidth(160);
- break;
- case 1:
- column.setText("OS");
- column.setWidth(100);
- break;
- case 2:
- column.setText("Transport");
- column.setWidth(60);
- break;
- case 3:
- column.setText("Host");
- column.setWidth(100);
- break;
- case 4:
- column.setText("Port");
- column.setWidth(40);
- break;
- }
- }
-
- peer_tree.setHeaderVisible(true);
- peer_tree.setFont(font);
- peer_tree.addListener(SWT.SetData, new Listener() {
- public void handleEvent(Event event) {
- TreeItem item = (TreeItem)event.item;
- PeerInfo info = findPeerInfo(item);
- if (info == null) {
- PeerInfo parent = findPeerInfo(item.getParentItem());
- if (parent == null) {
- item.setText("Invalid");
- }
- else {
- if (parent.children == null || parent.children_error != null) {
- loadChildren(parent);
- }
- updateItems(parent);
- }
- }
- else {
- fillItem(item, info);
- }
- }
- });
- peer_tree.addSelectionListener(new SelectionAdapter() {
@Override
- public void widgetDefaultSelected(SelectionEvent e) {
- TreeItem[] selections = peer_tree.getSelection();
- if (selections.length == 0) return;
- assert selections.length == 1;
- final PeerInfo info = findPeerInfo(selections[0]);
- if (info == null) return;
- new PeerPropsDialog(getShell(), getImage(), info.attrs,
- info.peer instanceof TCFUserDefPeer).open();
- if (!(info.peer instanceof TCFUserDefPeer)) return;
- Protocol.invokeLater(new Runnable() {
- public void run() {
- ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
- TCFUserDefPeer.savePeers();
- }
- });
- }
- @Override
- public void widgetSelected(SelectionEvent e) {
- update_peer_buttons.run();
- TreeItem[] selections = peer_tree.getSelection();
- if (selections.length > 0) {
- assert selections.length == 1;
- PeerInfo info = findPeerInfo(selections[0]);
- if (info != null) peer_id_text.setText(getPath(info));
- }
+ public void widgetSelected(SelectionEvent evt) {
+ handleProjectButtonSelected();
+ updateLaunchConfigurationDialog();
}
});
-
- createPeerButtons(composite);
}
- private void createPeerButtons(Composite parent) {
- Font font = parent.getFont();
- Composite composite = new Composite(parent, SWT.NONE);
+ private void createApplicationGroup(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
GridLayout layout = new GridLayout();
- composite.setFont(font);
- composite.setLayout(layout);
- composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setText("Application");
- final Button button_new = new Button(composite, SWT.PUSH);
- button_new.setText("N&ew...");
- button_new.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
- button_new.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- final Map<String,String> attrs = new HashMap<String,String>();
- if (new PeerPropsDialog(getShell(), getImage(), attrs, true).open() != Window.OK) return;
- Protocol.invokeLater(new Runnable() {
- public void run() {
- new TCFUserDefPeer(attrs);
- TCFUserDefPeer.savePeers();
- }
- });
- }
- });
-
- final Button button_edit = new Button(composite, SWT.PUSH);
- button_edit.setText("E&dit...");
- button_edit.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
- button_edit.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- TreeItem[] selection = peer_tree.getSelection();
- if (selection.length == 0) return;
- final PeerInfo info = findPeerInfo(selection[0]);
- if (info == null) return;
- if (new PeerPropsDialog(getShell(), getImage(), info.attrs,
- info.peer instanceof TCFUserDefPeer).open() != Window.OK) return;
- if (!(info.peer instanceof TCFUserDefPeer)) return;
- Protocol.invokeLater(new Runnable() {
- public void run() {
- ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
- TCFUserDefPeer.savePeers();
- }
- });
- }
- });
+ createLocalExeFileGroup(group);
+ createRemoteExeFileGroup(group);
+ }
- final Button button_remove = new Button(composite, SWT.PUSH);
- button_remove.setText("&Remove");
- button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
- button_remove.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- TreeItem[] selection = peer_tree.getSelection();
- if (selection.length == 0) return;
- final PeerInfo info = findPeerInfo(selection[0]);
- if (info == null) return;
- if (!(info.peer instanceof TCFUserDefPeer)) return;
- Protocol.invokeLater(new Runnable() {
- public void run() {
- ((TCFUserDefPeer)info.peer).dispose();
- TCFUserDefPeer.savePeers();
- }
- });
+ private void createLocalExeFileGroup(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ comp.setLayoutData(gd);
+
+ Label program_label = new Label(comp, SWT.NONE);
+ program_label.setText("Local File Path:");
+ gd = new GridData();
+ gd.horizontalSpan = 3;
+ program_label.setLayoutData(gd);
+
+ local_program_text = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ local_program_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ local_program_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ updateLaunchConfigurationDialog();
}
});
-
- createVerticalSpacer(composite, 20);
- final Button button_test = new Button(composite, SWT.PUSH);
- button_test.setText("Run &Tests");
- button_test.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
- button_test.addSelectionListener(new SelectionAdapter() {
+ Button search_button = createPushButton(comp, "Search...", null);
+ search_button.addSelectionListener(new SelectionAdapter() {
@Override
- public void widgetSelected(SelectionEvent e) {
- TreeItem[] selection = peer_tree.getSelection();
- if (selection.length > 0) {
- assert selection.length == 1;
- runDiagnostics(selection[0], false);
- }
+ public void widgetSelected(SelectionEvent evt) {
+ handleSearchButtonSelected();
+ updateLaunchConfigurationDialog();
}
});
- final Button button_loop = new Button(composite, SWT.PUSH);
- button_loop.setText("Tests &Loop");
- button_loop.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
- button_loop.addSelectionListener(new SelectionAdapter() {
+ Button browse_button = createPushButton(comp, "Browse...", null);
+ browse_button.addSelectionListener(new SelectionAdapter() {
@Override
- public void widgetSelected(SelectionEvent e) {
- TreeItem[] selection = peer_tree.getSelection();
- if (selection.length > 0) {
- assert selection.length == 1;
- runDiagnostics(selection[0], true);
- }
+ public void widgetSelected(SelectionEvent evt) {
+ handleBinaryBrowseButtonSelected();
+ updateLaunchConfigurationDialog();
}
});
-
- update_peer_buttons = new Runnable() {
-
- public void run() {
- PeerInfo info = null;
- TreeItem[] selection = peer_tree.getSelection();
- if (selection.length > 0) info = findPeerInfo(selection[0]);
- button_edit.setEnabled(info != null);
- button_remove.setEnabled(info != null && info.peer instanceof TCFUserDefPeer);
- button_test.setEnabled(info != null);
- button_loop.setEnabled(info != null);
- }
- };
- update_peer_buttons.run();
}
- private void createProgramGroup(Composite parent) {
- display = parent.getDisplay();
-
- Font font = parent.getFont();
+ private void createRemoteExeFileGroup(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ comp.setLayoutData(gd);
- Group group = new Group(parent, SWT.NONE);
- GridLayout top_layout = new GridLayout();
- group.setLayout(top_layout);
- group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- group.setFont(font);
- group.setText("Program");
+ Label program_label = new Label(comp, SWT.NONE);
+ program_label.setText("Remote File Path:");
+ gd = new GridData();
+ gd.horizontalSpan = 3;
+ program_label.setLayoutData(gd);
- program_text = new Text(group, SWT.SINGLE | SWT.BORDER);
- program_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- program_text.setFont(font);
- program_text.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent e) {
+ remote_program_text = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ remote_program_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ remote_program_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
updateLaunchConfigurationDialog();
}
});
}
+
+ private void createWorkingDirGroup(Composite comp) {
+ Group group = new Group(comp, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setText("Working directory");
+
+ working_dir_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ working_dir_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ default_dir_button = new Button(group, SWT.CHECK);
+ default_dir_button.setText("Use default");
+ default_dir_button.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
+ }
- @Override
- public void dispose() {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- for (Iterator<LocatorListener> i = listeners.keySet().iterator(); i.hasNext();) {
- LocatorListener listener = i.next();
- listeners.get(listener).removeListener(listener);
+ private ITCFLaunchContext getLaunchContext(IProject project) {
+ try {
+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.PLUGIN_ID, "launch_context");
+ IExtension[] extensions = point.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ try {
+ Bundle bundle = Platform.getBundle(extensions[i].getNamespaceIdentifier());
+ bundle.start();
+ IConfigurationElement[] e = extensions[i].getConfigurationElements();
+ for (int j = 0; j < e.length; j++) {
+ String nm = e[j].getName();
+ if (nm.equals("class")) { //$NON-NLS-1$
+ Class<?> c = bundle.loadClass(e[j].getAttribute("name")); //$NON-NLS-1$
+ ITCFLaunchContext launch_context = (ITCFLaunchContext)c.newInstance();
+ if (project != null) {
+ if (launch_context.isSupportedProject(project)) return launch_context;
+ }
+ else {
+ if (launch_context.isActive()) return launch_context;
+ }
+ }
+ }
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot access launch context extension points", x);
}
- listeners.clear();
- display = null;
}
- });
- super.dispose();
+ }
+ catch (Exception x) {
+ Activator.log("Cannot access launch context extension points", x);
+ }
+ return null;
}
- public String getName() {
- return "Main";
+ private void createTerminalOption(Composite parent, int colSpan) {
+ Composite terminal_comp = new Composite(parent, SWT.NONE);
+ GridLayout terminal_layout = new GridLayout();
+ terminal_layout.numColumns = 1;
+ terminal_layout.marginHeight = 0;
+ terminal_layout.marginWidth = 0;
+ terminal_comp.setLayout(terminal_layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = colSpan;
+ terminal_comp.setLayoutData(gd);
+
+ terminal_button = createCheckButton(terminal_comp, "Use Terminal");
+ terminal_button.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ terminal_button.setEnabled(true);
}
-
- @Override
- public Image getImage() {
- return ImageCache.getImage(ImageCache.IMG_TCF);
+
+ public void initializeFrom(ILaunchConfiguration config) {
+ updateProjectFromConfig(config);
+ updateLocalProgramFromConfig(config);
+ updateRemoteProgramFromConfig(config);
+ updateTerminalFromConfig(config);
+ updateWorkingDirFromConfig(config);
}
- public void initializeFrom(ILaunchConfiguration configuration) {
+ private void updateTerminalFromConfig(ILaunchConfiguration config) {
+ boolean use_terminal = true;
try {
- String id = configuration.getAttribute(
- TCFLaunchDelegate.ATTR_PEER_ID, (String)null);
- if (id != null) {
- peer_id_text.setText(id);
- TreeItem item = findItem(findPeerInfo(id));
- if (item != null) {
- peer_tree.setSelection(item);
- update_peer_buttons.run();
- }
- }
- program_text.setText(configuration.getAttribute(
- TCFLaunchDelegate.ATTR_PROGRAM_FILE, "")); //$NON-NLS-1$
+ use_terminal = config.getAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, true);
}
catch (CoreException e) {
- setErrorMessage(e.getMessage());
+ Activator.log(e);
}
+ terminal_button.setSelection(use_terminal);
}
- public boolean isValid(ILaunchConfiguration launchConfig) {
- String id = peer_id_text.getText().trim();
- if (id.length() == 0) {
- setErrorMessage("Specify a target ID");
- return false;
+ private void updateProjectFromConfig(ILaunchConfiguration config) {
+ String project_name = "";
+ try {
+ project_name = config.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
}
- setErrorMessage(null);
- return super.isValid(launchConfig);
+ catch (CoreException ce) {
+ Activator.log(ce);
+ }
+ project_text.setText(project_name);
}
- public void performApply(ILaunchConfigurationWorkingCopy configuration) {
- String id = peer_id_text.getText().trim();
- if (id.length() == 0) id = null;
- configuration.setAttribute(TCFLaunchDelegate.ATTR_PEER_ID, id);
- String nm = program_text.getText().trim();
- if (nm.length() == 0) nm = null;
- configuration.setAttribute(TCFLaunchDelegate.ATTR_PROGRAM_FILE, nm);
+ private void updateLocalProgramFromConfig(ILaunchConfiguration config) {
+ String program_name = "";
+ try {
+ program_name = config.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, "");
+ }
+ catch (CoreException ce) {
+ Activator.log(ce);
+ }
+ local_program_text.setText(program_name);
}
- public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
- configuration.setAttribute(TCFLaunchDelegate.ATTR_PEER_ID, "TCFLocal");
- configuration.setAttribute(TCFLaunchDelegate.ATTR_PROGRAM_FILE, (String)null);
+ private void updateRemoteProgramFromConfig(ILaunchConfiguration config) {
+ String program_name = "";
+ try {
+ program_name = config.getAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, "");
+ }
+ catch (CoreException ce) {
+ Activator.log(ce);
+ }
+ remote_program_text.setText(program_name);
}
-
- private LocatorListener createLocatorListener(PeerInfo peer, ILocator locator) {
- assert Protocol.isDispatchThread();
- Map<String,IPeer> map = locator.getPeers();
- PeerInfo[] buf = new PeerInfo[map.size()];
- int n = 0;
- for (IPeer p : map.values()) {
- PeerInfo info = new PeerInfo();
- info.parent = peer;
- info.index = n;
- info.id = p.getID();
- info.attrs = new HashMap<String,String>(p.getAttributes());
- info.peer = p;
- buf[n++] = info;
+
+ private void updateWorkingDirFromConfig(ILaunchConfiguration config) {
+ String name = "";
+ try {
+ name = config.getAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, ""); //$NON-NLS-1$
+ }
+ catch (CoreException ce) {
+ Activator.log(ce);
}
- LocatorListener listener = new LocatorListener(peer);
- listeners.put(listener, locator);
- locator.addListener(listener);
- setChildren(peer, null, buf);
- return listener;
+ working_dir_text.setText(name);
}
-
- private boolean canHaveChildren(PeerInfo parent) {
- return parent == peer_info || parent.attrs.get(IPeer.ATTR_PROXY) != null;
+
+ private IProject getProject() {
+ String name = project_text.getText().trim();
+ if (name.length() == 0) return null;
+ return ResourcesPlugin.getWorkspace().getRoot().getProject(name);
}
-
- private void loadChildren(final PeerInfo parent) {
- assert Thread.currentThread() == display.getThread();
- if (parent.children_pending) return;
- if (!canHaveChildren(parent)) {
- if (parent.children == null) updateItems(parent);
+
+ public void performApply(ILaunchConfigurationWorkingCopy config) {
+ config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, project_text.getText());
+ config.setAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, local_program_text.getText());
+ config.setAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, remote_program_text.getText());
+ config.setAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, working_dir_text.getText());
+ config.setAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, terminal_button.getSelection());
+ }
+
+ /**
+ * Show a dialog that lists all executable files in currently selected project.
+ */
+ private void handleSearchButtonSelected() {
+ IProject project = getProject();
+ if (project == null) {
+ MessageDialog.openInformation(getShell(),
+ "Project required",
+ "Enter project before searching for program");
return;
}
- parent.children_pending = true;
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- if (parent == peer_info) {
- createLocatorListener(peer_info, Protocol.getLocator());
- }
- else {
- final IChannel channel = parent.peer.openChannel();
- final LocatorListener[] listener = new LocatorListener[1];
- channel.addChannelListener(new IChannelListener() {
- public void congestionLevel(int level) {
- }
- public void onChannelClosed(Throwable error) {
- setChildren(parent, error, new PeerInfo[0]);
- if (listener[0] != null) listeners.remove(listener[0]);
- }
- public void onChannelOpened() {
- ILocator locator = channel.getRemoteService(ILocator.class);
- if (locator == null) {
- channel.close();
- }
- else {
- listener[0] = createLocatorListener(parent, locator);
- }
- }
- });
- }
- }
- });
+ ITCFLaunchContext launch_context = getLaunchContext(project);
+ if (launch_context == null) return;
+ String path = launch_context.chooseBinary(getShell(), project);
+ if (path != null) local_program_text.setText(path);
}
-
- private void setChildren(final PeerInfo parent, final Throwable error, final PeerInfo[] children) {
- assert Protocol.isDispatchThread();
- display.asyncExec(new Runnable() {
- public void run() {
- parent.children_pending = false;
- parent.children = children;
- parent.children_error = error;
- updateItems(parent);
- }
- });
+
+ /**
+ * Show a dialog that lets the user select a project. This in turn provides context for the main
+ * type, allowing the user to key a main type name, or constraining the search for main types to
+ * the specified project.
+ */
+ private void handleBinaryBrowseButtonSelected() {
+ FileDialog file_dialog = new FileDialog(getShell(), SWT.NONE);
+ file_dialog.setFileName(local_program_text.getText());
+ String path = file_dialog.open();
+ if (path != null) local_program_text.setText(path);
}
-
- private void updateItems(PeerInfo parent) {
- assert Thread.currentThread() == display.getThread();
- if (!canHaveChildren(parent)) {
- parent.children = new PeerInfo[0];
- parent.children_error = null;
- }
- PeerInfo[] arr = parent.children;
- TreeItem[] items = null;
- if (arr == null || parent.children_error != null) {
- if (parent == peer_info) {
- peer_tree.setItemCount(1);
- items = peer_tree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- item.setItemCount(1);
- items = item.getItems();
- }
- if (parent.children_pending) {
- items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- items[0].setText("Loading...");
- }
- else if (parent.children_error != null) {
- String msg = parent.children_error.getMessage().replace('\n', ' ');
- items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
- items[0].setText(msg);
- }
- else {
- items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
- items[0].setText("Invalid children list");
- }
- int n = peer_tree.getColumnCount();
- for (int i = 1; i < n; i++) items[0].setText(i, "");
- items[0].setItemCount(0);
+
+ /**
+ * Show a dialog that lets the user select a project. This in turn provides context for the main
+ * type, allowing the user to key a main type name, or constraining the search for main types to
+ * the specified project.
+ */
+ private void handleProjectButtonSelected() {
+ try {
+ IProject project = chooseProject();
+ if (project == null) return;
+ project_text.setText(project.getName());
}
- else {
- if (parent == peer_info) {
- peer_tree.setItemCount(arr.length);
- items = peer_tree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- item.setItemCount(arr.length);
- items = item.getItems();
- }
- assert items.length == arr.length;
- for (int i = 0; i < items.length; i++) fillItem(items[i], arr[i]);
- String id = peer_id_text.getText();
- TreeItem item = findItem(findPeerInfo(id));
- if (item != null) {
- peer_tree.setSelection(item);
- update_peer_buttons.run();
- }
+ catch (Exception e) {
+ Activator.log("Cannot get project description", e);
}
}
- private PeerInfo findPeerInfo(TreeItem item) {
- assert Thread.currentThread() == display.getThread();
- if (item == null) return peer_info;
- TreeItem parent = item.getParentItem();
- PeerInfo info = findPeerInfo(parent);
- if (info == null) return null;
- if (info.children == null) return null;
- if (info.children_error != null) return null;
- int i = parent == null ? peer_tree.indexOf(item) : parent.indexOf(item);
- if (i < 0 || i >= info.children.length) return null;
- assert info.children[i].index == i;
- return info.children[i];
- }
-
- private PeerInfo findPeerInfo(String path) {
- int i = path.lastIndexOf('/');
- String id = null;
- PeerInfo[] arr = null;
- if (i < 0) {
- arr = peer_info.children;
- id = path;
- }
- else {
- PeerInfo p = findPeerInfo(path.substring(0, i));
- if (p == null) return null;
- arr = p.children;
- id = path.substring(i + 1);
+ /**
+ * Show project list dialog and return the first selected project, or null.
+ */
+ private IProject chooseProject() {
+ try {
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ ILabelProvider label_provider = new LabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ if (element == null) return "";
+ return ((IProject)element).getName();
+ }
+ };
+ ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), label_provider);
+ dialog.setTitle("Project Selection");
+ dialog.setMessage("Choose project to constrain search for program");
+ dialog.setElements(projects);
+
+ IProject cProject = getProject();
+ if (cProject != null) dialog.setInitialSelections(new Object[]{cProject});
+ if (dialog.open() == Window.OK) return (IProject)dialog.getFirstResult();
}
- if (arr == null) return null;
- for (int n = 0; n < arr.length; n++) {
- if (arr[n].id.equals(id)) return arr[n];
+ catch (Exception e) {
+ Activator.log("Cannot show project list dialog", e);
}
return null;
}
-
- private TreeItem findItem(PeerInfo info) {
- if (info == null) return null;
- assert info.parent != null;
- if (info.parent == peer_info) {
- return peer_tree.getItem(info.index);
- }
- TreeItem i = findItem(info.parent);
- if (i == null) return null;
- peer_tree.showItem(i);
- return i.getItem(info.index);
- }
-
- private void runDiagnostics(TreeItem item, boolean loop) {
- final Shell shell = new Shell(getShell(), SWT.TITLE | SWT.PRIMARY_MODAL);
- GridLayout layout = new GridLayout();
- layout.verticalSpacing = 0;
- layout.numColumns = 2;
- shell.setLayout(layout);
- shell.setText("Running Diagnostics...");
- CLabel label = new CLabel(shell, SWT.NONE);
- label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
- label.setText("Running Diagnostics...");
- final TCFTestSuite[] test = new TCFTestSuite[1];
- Button button_cancel = new Button(shell, SWT.PUSH);
- button_cancel.setText("&Cancel");
- button_cancel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
- button_cancel.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- Protocol.invokeLater(new Runnable() {
- public void run() {
- if (test[0] != null) test[0].cancel();
- }
- });
+
+ @Override
+ public boolean isValid(ILaunchConfiguration config) {
+ setErrorMessage(null);
+ setMessage(null);
+
+ String project_name = project_text.getText().trim();
+ if (project_name.length() != 0) {
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(project_name);
+ if (!project.exists()) {
+ setErrorMessage("Project does not exist");
+ return false;
}
- });
- createVerticalSpacer(shell, 0);
- ProgressBar bar = new ProgressBar(shell, SWT.HORIZONTAL);
- bar.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1));
- shell.setDefaultButton(button_cancel);
- shell.pack();
- shell.setSize(483, shell.getSize().y);
- Rectangle rc0 = getShell().getBounds();
- Rectangle rc1 = shell.getBounds();
- shell.setLocation(rc0.x + (rc0.width - rc1.width) / 2, rc0.y + (rc0.height - rc1.height) / 2);
- shell.setVisible(true);
- runDiagnostics(item, loop, test, shell, label, bar);
- }
-
- private void runDiagnostics(final TreeItem item, final boolean loop, final TCFTestSuite[] test,
- final Shell shell, final CLabel label, final ProgressBar bar) {
- final TCFTestSuite.TestListener done = new TCFTestSuite.TestListener() {
- private String last_text = "";
- private int last_count = 0;
- private int last_total = 0;
- public void progress(final String label_text, final int count_done, final int count_total) {
- assert test[0] != null;
- if ((label_text == null || last_text.equals(label_text)) &&
- last_total == count_total &&
- (count_done - last_count) / (float)count_total < 0.02f) return;
- if (label_text != null) last_text = label_text;
- last_total = count_total;
- last_count = count_done;
- display.asyncExec(new Runnable() {
- public void run() {
- label.setText(last_text);
- bar.setMinimum(0);
- bar.setMaximum(last_total);
- bar.setSelection(last_count);
- }
- });
+ if (!project.isOpen()) {
+ setErrorMessage("Project must be opened");
+ return false;
}
- public void done(final Collection<Throwable> errors) {
- assert test[0] != null;
- final boolean b = test[0].isCanceled();
- test[0] = null;
- display.asyncExec(new Runnable() {
- public void run() {
- if (errors.size() > 0) {
- shell.dispose();
- new TestErrorsDialog(getControl().getShell(),
- ImageCache.getImage(ImageCache.IMG_TCF), errors).open();
- }
- else if (loop && !b && display != null) {
- runDiagnostics(item, true, test, shell, label, bar);
- }
- else {
- shell.dispose();
- }
- }
- });
+ }
+ String local_name = local_program_text.getText().trim();
+ if (local_name.equals(".") || local_name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
+ setErrorMessage("Invalid local program name");
+ return false;
+ }
+ String remote_name = remote_program_text.getText().trim();
+ if (remote_name.equals(".") || remote_name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
+ setErrorMessage("Invalid remote program name");
+ return false;
+ }
+ if (local_name.length() > 0) {
+ IProject project = getProject();
+ IPath program_path = new Path(local_name);
+ if (!program_path.isAbsolute()) {
+ if (project == null || !project.getFile(local_name).exists()) {
+ setErrorMessage("Program does not exist");
+ return false;
+ }
+ program_path = project.getFile(local_name).getLocation();
}
- };
- final PeerInfo info = findPeerInfo(item);
- Protocol.invokeLater(new Runnable() {
- public void run() {
+ else {
+ File file = program_path.toFile();
+ if (!file.exists()) {
+ setErrorMessage("Program file does not exist");
+ return false;
+ }
+ if (file.isDirectory()) {
+ setErrorMessage("Program path is directory name");
+ return false;
+ }
+ }
+ if (project != null) {
try {
- test[0] = new TCFTestSuite(info.peer, done);
+ ITCFLaunchContext launch_context = getLaunchContext(project);
+ if (launch_context != null && !launch_context.isBinary(project, program_path)) {
+ setErrorMessage("Program is not a recongnized executable");
+ return false;
+ }
}
- catch (Throwable x) {
- ArrayList<Throwable> errors = new ArrayList<Throwable>();
- errors.add(x);
- done.done(errors);
+ catch (CoreException e) {
+ Activator.log(e);
+ setErrorMessage(e.getLocalizedMessage());
+ return false;
}
}
- });
+ }
+ return true;
}
-
- private void fillItem(TreeItem item, PeerInfo info) {
- String text[] = new String[5];
- text[0] = info.attrs.get(IPeer.ATTR_NAME);
- text[1] = info.attrs.get(IPeer.ATTR_OS_NAME);
- text[2] = info.attrs.get(IPeer.ATTR_TRANSPORT_NAME);
- text[3] = info.attrs.get(IPeer.ATTR_IP_HOST);
- text[4] = info.attrs.get(IPeer.ATTR_IP_PORT);
- item.setText(text);
- item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- item.setImage(ImageCache.getImage(getImageName(info)));
- if (!canHaveChildren(info)) item.setItemCount(0);
- else if (info.children == null || info.children_error != null) item.setItemCount(1);
- else item.setItemCount(info.children.length);
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+ config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
+ config.setAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, true);
+ ITCFLaunchContext launch_context = getLaunchContext(null);
+ if (launch_context != null) launch_context.setDefaults(getLaunchConfigurationDialog(), config);
}
-
- private String getPath(PeerInfo info) {
- if (info.parent == peer_info) return info.id;
- return getPath(info.parent) + "/" + info.id;
+
+ public String getName() {
+ return "Main";
}
-
- private String getImageName(PeerInfo info) {
- return ImageCache.IMG_TCF;
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImage(ImageCache.IMG_TCF);
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTabGroup.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTabGroup.java
index 39c53c999..c8676502b 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTabGroup.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTabGroup.java
@@ -25,6 +25,7 @@ public class TCFTabGroup extends AbstractLaunchConfigurationTabGroup {
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
setTabs(new ILaunchConfigurationTab[] {
new TCFMainTab(),
+ new TCFTargetTab(),
new TCFArgumentsTab(),
new EnvironmentTab(),
new SourceLookupTab(),
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java
new file mode 100644
index 000000000..6d0bace5d
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java
@@ -0,0 +1,801 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFUserDefPeer;
+import org.eclipse.tm.internal.tcf.debug.tests.TCFTestSuite;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.protocol.IChannel.IChannelListener;
+import org.eclipse.tm.tcf.services.ILocator;
+
+
+/**
+ * Launch configuration dialog tab to specify the Target Communication Framework
+ * configuration.
+ */
+public class TCFTargetTab extends AbstractLaunchConfigurationTab {
+
+ private Text peer_id_text;
+ private Tree peer_tree;
+ private Runnable update_peer_buttons;
+ private final PeerInfo peer_info = new PeerInfo();
+ private Display display;
+
+ private final Map<LocatorListener,ILocator> listeners = new HashMap<LocatorListener,ILocator>();
+
+ private static class PeerInfo {
+ PeerInfo parent;
+ int index;
+ String id;
+ Map<String,String> attrs;
+ PeerInfo[] children;
+ boolean children_pending;
+ Throwable children_error;
+ IPeer peer;
+ }
+
+ private class LocatorListener implements ILocator.LocatorListener {
+
+ private final PeerInfo parent;
+
+ LocatorListener(PeerInfo parent) {
+ this.parent = parent;
+ }
+
+ public void peerAdded(final IPeer peer) {
+ if (display == null) return;
+ final String id = peer.getID();
+ final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ PeerInfo[] buf = new PeerInfo[arr.length + 1];
+ System.arraycopy(arr, 0, buf, 0, arr.length);
+ PeerInfo info = new PeerInfo();
+ info.parent = parent;
+ info.index = arr.length;
+ info.id = id;
+ info.attrs = attrs;
+ info.peer = peer;
+ buf[arr.length] = info;
+ parent.children = buf;
+ updateItems(parent);
+ }
+ });
+ }
+
+ public void peerChanged(final IPeer peer) {
+ if (display == null) return;
+ final String id = peer.getID();
+ final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i].id.equals(id)) {
+ arr[i].attrs = attrs;
+ arr[i].peer = peer;
+ loadChildren(arr[i]);
+ updateItems(parent);
+ }
+ }
+ }
+ });
+ }
+
+ public void peerRemoved(final String id) {
+ if (display == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ PeerInfo[] buf = new PeerInfo[arr.length - 1];
+ int j = 0;
+ for (int i = 0; i < arr.length; i++) {
+ if (!arr[i].id.equals(id)) {
+ buf[j++] = arr[i];
+ }
+ }
+ parent.children = buf;
+ updateItems(parent);
+ }
+ });
+ }
+
+ public void peerHeartBeat(final String id) {
+ if (display == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i].id.equals(id)) {
+ if (arr[i].children_error != null) {
+ loadChildren(arr[i]);
+ }
+ break;
+ }
+ }
+ }
+ });
+ }
+ }
+
+ public void createControl(Composite parent) {
+ display = parent.getDisplay();
+ assert display != null;
+
+ Font font = parent.getFont();
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, true);
+ comp.setLayout(layout);
+ comp.setFont(font);
+
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(gd);
+ setControl(comp);
+
+ createTargetGroup(comp);
+ }
+
+ private void createTargetGroup(Composite parent) {
+ Font font = parent.getFont();
+
+ Group group = new Group(parent, SWT.NONE);
+ GridLayout top_layout = new GridLayout();
+ top_layout.verticalSpacing = 0;
+ top_layout.numColumns = 2;
+ group.setLayout(top_layout);
+ group.setLayoutData(new GridData(GridData.FILL_BOTH));
+ group.setFont(font);
+ group.setText("Target");
+
+ createVerticalSpacer(group, top_layout.numColumns);
+
+ Label host_label = new Label(group, SWT.NONE);
+ host_label.setText("Target ID:");
+ host_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ host_label.setFont(font);
+
+ peer_id_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ peer_id_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ peer_id_text.setFont(font);
+ peer_id_text.setEditable(false);
+ peer_id_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ createVerticalSpacer(group, top_layout.numColumns);
+
+ Label peer_label = new Label(group, SWT.NONE);
+ peer_label.setText("&Available targets:");
+ peer_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ peer_label.setFont(font);
+
+ loadChildren(peer_info);
+ createPeerListArea(group);
+ }
+
+ private void createPeerListArea(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
+
+ peer_tree = new Tree(composite, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ gd.minimumHeight = 150;
+ gd.minimumWidth = 470;
+ peer_tree.setLayoutData(gd);
+
+ for (int i = 0; i < 5; i++) {
+ TreeColumn column = new TreeColumn(peer_tree, SWT.LEAD, i);
+ column.setMoveable(true);
+ switch (i) {
+ case 0:
+ column.setText("Name");
+ column.setWidth(160);
+ break;
+ case 1:
+ column.setText("OS");
+ column.setWidth(100);
+ break;
+ case 2:
+ column.setText("Transport");
+ column.setWidth(60);
+ break;
+ case 3:
+ column.setText("Host");
+ column.setWidth(100);
+ break;
+ case 4:
+ column.setText("Port");
+ column.setWidth(40);
+ break;
+ }
+ }
+
+ peer_tree.setHeaderVisible(true);
+ peer_tree.setFont(font);
+ peer_tree.addListener(SWT.SetData, new Listener() {
+ public void handleEvent(Event event) {
+ TreeItem item = (TreeItem)event.item;
+ PeerInfo info = findPeerInfo(item);
+ if (info == null) {
+ PeerInfo parent = findPeerInfo(item.getParentItem());
+ if (parent == null) {
+ item.setText("Invalid");
+ }
+ else {
+ if (parent.children == null || parent.children_error != null) {
+ loadChildren(parent);
+ }
+ updateItems(parent);
+ }
+ }
+ else {
+ fillItem(item, info);
+ }
+ }
+ });
+ peer_tree.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ TreeItem[] selections = peer_tree.getSelection();
+ if (selections.length == 0) return;
+ assert selections.length == 1;
+ final PeerInfo info = findPeerInfo(selections[0]);
+ if (info == null) return;
+ new PeerPropsDialog(getShell(), getImage(), info.attrs,
+ info.peer instanceof TCFUserDefPeer).open();
+ if (!(info.peer instanceof TCFUserDefPeer)) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ update_peer_buttons.run();
+ TreeItem[] selections = peer_tree.getSelection();
+ if (selections.length > 0) {
+ assert selections.length == 1;
+ PeerInfo info = findPeerInfo(selections[0]);
+ if (info != null) peer_id_text.setText(getPath(info));
+ }
+ }
+ });
+
+ createPeerButtons(composite);
+ }
+
+ private void createPeerButtons(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+
+ final Button button_new = new Button(composite, SWT.PUSH);
+ button_new.setText("N&ew...");
+ button_new.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_new.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final Map<String,String> attrs = new HashMap<String,String>();
+ if (new PeerPropsDialog(getShell(), getImage(), attrs, true).open() != Window.OK) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ new TCFUserDefPeer(attrs);
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ });
+
+ final Button button_edit = new Button(composite, SWT.PUSH);
+ button_edit.setText("E&dit...");
+ button_edit.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_edit.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem[] selection = peer_tree.getSelection();
+ if (selection.length == 0) return;
+ final PeerInfo info = findPeerInfo(selection[0]);
+ if (info == null) return;
+ if (new PeerPropsDialog(getShell(), getImage(), info.attrs,
+ info.peer instanceof TCFUserDefPeer).open() != Window.OK) return;
+ if (!(info.peer instanceof TCFUserDefPeer)) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ });
+
+ final Button button_remove = new Button(composite, SWT.PUSH);
+ button_remove.setText("&Remove");
+ button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_remove.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem[] selection = peer_tree.getSelection();
+ if (selection.length == 0) return;
+ final PeerInfo info = findPeerInfo(selection[0]);
+ if (info == null) return;
+ if (!(info.peer instanceof TCFUserDefPeer)) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ ((TCFUserDefPeer)info.peer).dispose();
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ });
+
+ createVerticalSpacer(composite, 20);
+
+ final Button button_test = new Button(composite, SWT.PUSH);
+ button_test.setText("Run &Tests");
+ button_test.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_test.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem[] selection = peer_tree.getSelection();
+ if (selection.length > 0) {
+ assert selection.length == 1;
+ runDiagnostics(selection[0], false);
+ }
+ }
+ });
+
+ final Button button_loop = new Button(composite, SWT.PUSH);
+ button_loop.setText("Tests &Loop");
+ button_loop.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_loop.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem[] selection = peer_tree.getSelection();
+ if (selection.length > 0) {
+ assert selection.length == 1;
+ runDiagnostics(selection[0], true);
+ }
+ }
+ });
+
+ update_peer_buttons = new Runnable() {
+
+ public void run() {
+ PeerInfo info = null;
+ TreeItem[] selection = peer_tree.getSelection();
+ if (selection.length > 0) info = findPeerInfo(selection[0]);
+ button_edit.setEnabled(info != null);
+ button_remove.setEnabled(info != null && info.peer instanceof TCFUserDefPeer);
+ button_test.setEnabled(info != null);
+ button_loop.setEnabled(info != null);
+ }
+ };
+ update_peer_buttons.run();
+ }
+
+ @Override
+ public void dispose() {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ for (Iterator<LocatorListener> i = listeners.keySet().iterator(); i.hasNext();) {
+ LocatorListener listener = i.next();
+ listeners.get(listener).removeListener(listener);
+ }
+ listeners.clear();
+ display = null;
+ }
+ });
+ super.dispose();
+ }
+
+ public String getName() {
+ return "Target";
+ }
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImage(ImageCache.IMG_TARGET_TAB);
+ }
+
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ String id = configuration.getAttribute(
+ TCFLaunchDelegate.ATTR_PEER_ID, (String)null);
+ if (id != null) {
+ peer_id_text.setText(id);
+ TreeItem item = findItem(findPeerInfo(id));
+ if (item != null) {
+ peer_tree.setSelection(item);
+ update_peer_buttons.run();
+ }
+ }
+ }
+ catch (CoreException e) {
+ setErrorMessage(e.getMessage());
+ }
+ }
+
+ public boolean isValid(ILaunchConfiguration launchConfig) {
+ String id = peer_id_text.getText().trim();
+ if (id.length() == 0) {
+ setErrorMessage("Specify a target ID");
+ return false;
+ }
+ setErrorMessage(null);
+ return super.isValid(launchConfig);
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ String id = peer_id_text.getText().trim();
+ if (id.length() == 0) id = null;
+ configuration.setAttribute(TCFLaunchDelegate.ATTR_PEER_ID, id);
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(TCFLaunchDelegate.ATTR_PEER_ID, "TCFLocal");
+ }
+
+ private LocatorListener createLocatorListener(PeerInfo peer, ILocator locator) {
+ assert Protocol.isDispatchThread();
+ Map<String,IPeer> map = locator.getPeers();
+ PeerInfo[] buf = new PeerInfo[map.size()];
+ int n = 0;
+ for (IPeer p : map.values()) {
+ PeerInfo info = new PeerInfo();
+ info.parent = peer;
+ info.index = n;
+ info.id = p.getID();
+ info.attrs = new HashMap<String,String>(p.getAttributes());
+ info.peer = p;
+ buf[n++] = info;
+ }
+ LocatorListener listener = new LocatorListener(peer);
+ listeners.put(listener, locator);
+ locator.addListener(listener);
+ setChildren(peer, null, buf);
+ return listener;
+ }
+
+ private boolean canHaveChildren(PeerInfo parent) {
+ return parent == peer_info || parent.attrs.get(IPeer.ATTR_PROXY) != null;
+ }
+
+ private void loadChildren(final PeerInfo parent) {
+ assert Thread.currentThread() == display.getThread();
+ if (parent.children_pending) return;
+ if (!canHaveChildren(parent)) {
+ if (parent.children == null) updateItems(parent);
+ return;
+ }
+ parent.children_pending = true;
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ if (parent == peer_info) {
+ createLocatorListener(peer_info, Protocol.getLocator());
+ }
+ else {
+ final IChannel channel = parent.peer.openChannel();
+ final LocatorListener[] listener = new LocatorListener[1];
+ channel.addChannelListener(new IChannelListener() {
+ public void congestionLevel(int level) {
+ }
+ public void onChannelClosed(Throwable error) {
+ setChildren(parent, error, new PeerInfo[0]);
+ if (listener[0] != null) listeners.remove(listener[0]);
+ }
+ public void onChannelOpened() {
+ ILocator locator = channel.getRemoteService(ILocator.class);
+ if (locator == null) {
+ channel.close();
+ }
+ else {
+ listener[0] = createLocatorListener(parent, locator);
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+
+ private void setChildren(final PeerInfo parent, final Throwable error, final PeerInfo[] children) {
+ assert Protocol.isDispatchThread();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ parent.children_pending = false;
+ parent.children = children;
+ parent.children_error = error;
+ updateItems(parent);
+ }
+ });
+ }
+
+ private void updateItems(PeerInfo parent) {
+ if (display == null) return;
+ assert Thread.currentThread() == display.getThread();
+ if (!canHaveChildren(parent)) {
+ parent.children = new PeerInfo[0];
+ parent.children_error = null;
+ }
+ PeerInfo[] arr = parent.children;
+ TreeItem[] items = null;
+ if (arr == null || parent.children_error != null) {
+ if (parent == peer_info) {
+ peer_tree.setItemCount(1);
+ items = peer_tree.getItems();
+ }
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ item.setItemCount(1);
+ items = item.getItems();
+ }
+ if (parent.children_pending) {
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ items[0].setText("Loading...");
+ }
+ else if (parent.children_error != null) {
+ String msg = parent.children_error.getMessage().replace('\n', ' ');
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
+ items[0].setText(msg);
+ }
+ else {
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
+ items[0].setText("Invalid children list");
+ }
+ int n = peer_tree.getColumnCount();
+ for (int i = 1; i < n; i++) items[0].setText(i, "");
+ items[0].setItemCount(0);
+ }
+ else {
+ if (parent == peer_info) {
+ peer_tree.setItemCount(arr.length);
+ items = peer_tree.getItems();
+ }
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ item.setItemCount(arr.length);
+ items = item.getItems();
+ }
+ assert items.length == arr.length;
+ for (int i = 0; i < items.length; i++) fillItem(items[i], arr[i]);
+ String id = peer_id_text.getText();
+ TreeItem item = findItem(findPeerInfo(id));
+ if (item != null) {
+ peer_tree.setSelection(item);
+ update_peer_buttons.run();
+ }
+ }
+ }
+
+ private PeerInfo findPeerInfo(TreeItem item) {
+ assert Thread.currentThread() == display.getThread();
+ if (item == null) return peer_info;
+ TreeItem parent = item.getParentItem();
+ PeerInfo info = findPeerInfo(parent);
+ if (info == null) return null;
+ if (info.children == null) return null;
+ if (info.children_error != null) return null;
+ int i = parent == null ? peer_tree.indexOf(item) : parent.indexOf(item);
+ if (i < 0 || i >= info.children.length) return null;
+ assert info.children[i].index == i;
+ return info.children[i];
+ }
+
+ private PeerInfo findPeerInfo(String path) {
+ int i = path.lastIndexOf('/');
+ String id = null;
+ PeerInfo[] arr = null;
+ if (i < 0) {
+ arr = peer_info.children;
+ id = path;
+ }
+ else {
+ PeerInfo p = findPeerInfo(path.substring(0, i));
+ if (p == null) return null;
+ arr = p.children;
+ id = path.substring(i + 1);
+ }
+ if (arr == null) return null;
+ for (int n = 0; n < arr.length; n++) {
+ if (arr[n].id.equals(id)) return arr[n];
+ }
+ return null;
+ }
+
+ private TreeItem findItem(PeerInfo info) {
+ if (info == null) return null;
+ assert info.parent != null;
+ if (info.parent == peer_info) {
+ return peer_tree.getItem(info.index);
+ }
+ TreeItem i = findItem(info.parent);
+ if (i == null) return null;
+ peer_tree.showItem(i);
+ return i.getItem(info.index);
+ }
+
+ private void runDiagnostics(TreeItem item, boolean loop) {
+ final Shell shell = new Shell(getShell(), SWT.TITLE | SWT.PRIMARY_MODAL);
+ GridLayout layout = new GridLayout();
+ layout.verticalSpacing = 0;
+ layout.numColumns = 2;
+ shell.setLayout(layout);
+ shell.setText("Running Diagnostics...");
+ CLabel label = new CLabel(shell, SWT.NONE);
+ label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ label.setText("Running Diagnostics...");
+ final TCFTestSuite[] test = new TCFTestSuite[1];
+ Button button_cancel = new Button(shell, SWT.PUSH);
+ button_cancel.setText("&Cancel");
+ button_cancel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
+ button_cancel.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (test[0] != null) test[0].cancel();
+ }
+ });
+ }
+ });
+ createVerticalSpacer(shell, 0);
+ ProgressBar bar = new ProgressBar(shell, SWT.HORIZONTAL);
+ bar.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1));
+ shell.setDefaultButton(button_cancel);
+ shell.pack();
+ shell.setSize(483, shell.getSize().y);
+ Rectangle rc0 = getShell().getBounds();
+ Rectangle rc1 = shell.getBounds();
+ shell.setLocation(rc0.x + (rc0.width - rc1.width) / 2, rc0.y + (rc0.height - rc1.height) / 2);
+ shell.setVisible(true);
+ runDiagnostics(item, loop, test, shell, label, bar);
+ }
+
+ private void runDiagnostics(final TreeItem item, final boolean loop, final TCFTestSuite[] test,
+ final Shell shell, final CLabel label, final ProgressBar bar) {
+ final TCFTestSuite.TestListener done = new TCFTestSuite.TestListener() {
+ private String last_text = "";
+ private int last_count = 0;
+ private int last_total = 0;
+ public void progress(final String label_text, final int count_done, final int count_total) {
+ assert test[0] != null;
+ if ((label_text == null || last_text.equals(label_text)) &&
+ last_total == count_total &&
+ (count_done - last_count) / (float)count_total < 0.02f) return;
+ if (label_text != null) last_text = label_text;
+ last_total = count_total;
+ last_count = count_done;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ label.setText(last_text);
+ bar.setMinimum(0);
+ bar.setMaximum(last_total);
+ bar.setSelection(last_count);
+ }
+ });
+ }
+ public void done(final Collection<Throwable> errors) {
+ assert test[0] != null;
+ final boolean b = test[0].isCanceled();
+ test[0] = null;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (errors.size() > 0) {
+ shell.dispose();
+ new TestErrorsDialog(getControl().getShell(),
+ ImageCache.getImage(ImageCache.IMG_TCF), errors).open();
+ }
+ else if (loop && !b && display != null) {
+ runDiagnostics(item, true, test, shell, label, bar);
+ }
+ else {
+ shell.dispose();
+ }
+ }
+ });
+ }
+ };
+ final PeerInfo info = findPeerInfo(item);
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ test[0] = new TCFTestSuite(info.peer, done);
+ }
+ catch (Throwable x) {
+ ArrayList<Throwable> errors = new ArrayList<Throwable>();
+ errors.add(x);
+ done.done(errors);
+ }
+ }
+ });
+ }
+
+ private void fillItem(TreeItem item, PeerInfo info) {
+ String text[] = new String[5];
+ text[0] = info.attrs.get(IPeer.ATTR_NAME);
+ text[1] = info.attrs.get(IPeer.ATTR_OS_NAME);
+ text[2] = info.attrs.get(IPeer.ATTR_TRANSPORT_NAME);
+ text[3] = info.attrs.get(IPeer.ATTR_IP_HOST);
+ text[4] = info.attrs.get(IPeer.ATTR_IP_PORT);
+ item.setText(text);
+ item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ item.setImage(ImageCache.getImage(getImageName(info)));
+ if (!canHaveChildren(info)) item.setItemCount(0);
+ else if (info.children == null || info.children_error != null) item.setItemCount(1);
+ else item.setItemCount(info.children.length);
+ }
+
+ private String getPath(PeerInfo info) {
+ if (info.parent == peer_info) return info.id;
+ return getPath(info.parent) + "/" + info.id;
+ }
+
+ private String getImageName(PeerInfo info) {
+ return ImageCache.IMG_TARGET_TAB;
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
index d49c91b12..6c7a232e6 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
@@ -295,24 +295,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
launch_node.dispose();
launch_node = null;
}
- final Throwable error = launch.getError();
- if (error != null) launch.setError(null);
- display.asyncExec(new Runnable() {
- public void run() {
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- if (window == null) return;
- IDebugView view = (IDebugView)window.getActivePage().findView(IDebugUIConstants.ID_DEBUG_VIEW);
- if (view != null) ((StructuredViewer)view.getViewer()).refresh(launch);
- if (error != null) {
- String msg = error.getLocalizedMessage();
- if (msg == null || msg.length() == 0) msg = error.getClass().getName();
- MessageBox mb = new MessageBox(window.getShell(), SWT.ICON_ERROR | SWT.OK);
- mb.setText("TCF Connection Error");
- mb.setMessage("Communication channel is closed.\n" + msg);
- mb.open();
- }
- }
- });
+ refreshLaunchView();
assert id2node.size() == 0;
}
@@ -381,6 +364,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
launch_node.addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
fireModelChanged();
}
+ else {
+ refreshLaunchView();
+ }
}
void dispose() {
@@ -634,6 +620,37 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
});
}
+ private void refreshLaunchView() {
+ final Throwable error = launch.getError();
+ if (error != null) launch.setError(null);
+ display.asyncExec(new Runnable() {
+ public void run() {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window == null) return;
+ IDebugView view = (IDebugView)window.getActivePage().findView(IDebugUIConstants.ID_DEBUG_VIEW);
+ if (view != null) ((StructuredViewer)view.getViewer()).refresh(launch);
+ if (error != null) {
+ StringBuffer buf = new StringBuffer();
+ Throwable err = error;
+ while (err != null) {
+ String msg = err.getLocalizedMessage();
+ if (msg == null || msg.length() == 0) msg = err.getClass().getName();
+ buf.append(msg);
+ err = err.getCause();
+ if (err != null) {
+ buf.append('\n');
+ buf.append("Caused by:\n");
+ }
+ }
+ MessageBox mb = new MessageBox(window.getShell(), SWT.ICON_ERROR | SWT.OK);
+ mb.setText("TCF Launch Error");
+ mb.setMessage(buf.toString());
+ mb.open();
+ }
+ }
+ });
+ }
+
/**
* Open an editor for given editor input.
* @param input - IEditorInput representing a source file to be shown in the editor
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFLaunchDelegate.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFLaunchDelegate.java
index b25cb9303..84edbff0d 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFLaunchDelegate.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFLaunchDelegate.java
@@ -27,9 +27,13 @@ public class TCFLaunchDelegate extends LaunchConfigurationDelegate {
public static final String
ATTR_PEER_ID = ITCFConstants.ID_TCF_DEBUG_MODEL + ".PeerID",
- ATTR_PROGRAM_FILE = ITCFConstants.ID_TCF_DEBUG_MODEL + ".ProgramFile",
+ ATTR_PROJECT_NAME = ITCFConstants.ID_TCF_DEBUG_MODEL + ".ProjectName",
+ ATTR_LOCAL_PROGRAM_FILE = ITCFConstants.ID_TCF_DEBUG_MODEL + ".LocalProgramFile",
+ ATTR_REMOTE_PROGRAM_FILE = ITCFConstants.ID_TCF_DEBUG_MODEL + ".ProgramFile",
+ ATTR_COPY_TO_REMOTE_FILE = ITCFConstants.ID_TCF_DEBUG_MODEL + ".CopyToRemote",
ATTR_PROGRAM_ARGUMENTS = ITCFConstants.ID_TCF_DEBUG_MODEL + ".ProgramArguments",
- ATTR_WORKING_DIRECTORY = ITCFConstants.ID_TCF_DEBUG_MODEL + ".WorkingDirectory";
+ ATTR_WORKING_DIRECTORY = ITCFConstants.ID_TCF_DEBUG_MODEL + ".WorkingDirectory",
+ ATTR_USE_TERMINAL = ITCFConstants.ID_TCF_DEBUG_MODEL + ".UseTerminal";
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
return new TCFLaunch(configuration, mode);
@@ -41,7 +45,7 @@ public class TCFLaunchDelegate extends LaunchConfigurationDelegate {
Protocol.invokeLater(new Runnable() {
public void run() {
try {
- String id = configuration.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, "");
+ String id = configuration.getAttribute(ATTR_PEER_ID, "");
IPeer peer = Protocol.getLocator().getPeers().get(id);
if (peer == null) throw new IOException("Cannot locate peer " + id);
((TCFLaunch)launch).launchTCF(mode, peer);
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java
index 357a0de94..76fac6768 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourcePathComputerDelegate.java
@@ -36,7 +36,7 @@ public class TCFSourcePathComputerDelegate implements ISourcePathComputerDelegat
ILaunchConfiguration configuration, IProgressMonitor monitor)
throws CoreException {
ISourceContainer sourceContainer = null;
- String path = configuration.getAttribute(TCFLaunchDelegate.ATTR_PROGRAM_FILE, (String)null);
+ String path = configuration.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, (String)null);
if (path != null) {
IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(path));
if (resource != null) {
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
index b7c30a78d..76bb99c13 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
@@ -10,14 +10,22 @@
*******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.model;
+import java.io.FileInputStream;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
@@ -31,7 +39,10 @@ import org.eclipse.tm.tcf.protocol.IPeer;
import org.eclipse.tm.tcf.protocol.IService;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IFileSystem;
import org.eclipse.tm.tcf.services.IProcesses;
+import org.eclipse.tm.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.tm.tcf.services.IFileSystem.IFileHandle;
import org.eclipse.tm.tcf.services.IProcesses.ProcessContext;
@@ -155,8 +166,10 @@ public class TCFLaunch extends Launch {
Protocol.invokeLater(done);
return;
}
- final String file = cfg.getAttribute(TCFLaunchDelegate.ATTR_PROGRAM_FILE, "");
- if (file.length() == 0) {
+ final String project = cfg.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
+ final String local_file = cfg.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, "");
+ final String remote_file = cfg.getAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, "");
+ if (local_file.length() == 0 && remote_file.length() == 0) {
Protocol.invokeLater(done);
return;
}
@@ -166,36 +179,138 @@ public class TCFLaunch extends Launch {
final boolean append = cfg.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
final boolean attach = mode.equals(ILaunchManager.DEBUG_MODE);
final IProcesses ps = channel.getRemoteService(IProcesses.class);
- if (ps == null) throw new Exception("Target does not provide Processes service");
- IProcesses.DoneGetEnvironment done_env = new IProcesses.DoneGetEnvironment() {
- public void doneGetEnvironment(IToken token, Exception error, Map<String,String> def) {
- if (error != null) {
- channel.terminate(error);
- return;
- }
- Map<String,String> vars = new HashMap<String,String>();
- if (append) vars.putAll(def);
- if (env != null) vars.putAll(env);
- ps.start(dir, file, toArgsArray(file, args), vars, attach, new IProcesses.DoneStart() {
- public void doneStart(IToken token, Exception error, ProcessContext process) {
+ Runnable r = new Runnable() {
+ public void run() {
+ if (ps == null) channel.terminate(new Exception("Target does not provide Processes service"));
+ IProcesses.DoneGetEnvironment done_env = new IProcesses.DoneGetEnvironment() {
+ public void doneGetEnvironment(IToken token, Exception error, Map<String,String> def) {
if (error != null) {
channel.terminate(error);
return;
}
- TCFLaunch.this.process = process;
- Protocol.invokeLater(done);
+ Map<String,String> vars = new HashMap<String,String>();
+ if (append) vars.putAll(def);
+ if (env != null) vars.putAll(env);
+ String file = remote_file;
+ if (file == null) file = getProgramPath(project, local_file);
+ if (file == null) {
+ channel.terminate(new Exception("Program does not exist"));
+ return;
+ }
+ ps.start(dir, file, toArgsArray(file, args), vars, attach, new IProcesses.DoneStart() {
+ public void doneStart(IToken token, Exception error, ProcessContext process) {
+ if (error != null) {
+ channel.terminate(error);
+ return;
+ }
+ TCFLaunch.this.process = process;
+ Protocol.invokeLater(done);
+ }
+ });
}
- });
+ };
+ if (append) ps.getEnvironment(done_env);
+ else done_env.doneGetEnvironment(null, null, null);
}
};
- if (append) ps.getEnvironment(done_env);
- else done_env.doneGetEnvironment(null, null, null);
+ if (local_file.length() == 0 || remote_file.length() == 0) r.run();
+ else copyToRemoteTarget(getProgramPath(project, local_file), remote_file, r);
}
catch (Exception x) {
channel.terminate(x);
}
}
+ private void copyToRemoteTarget(String local_file, String remote_file, final Runnable done) {
+ if (local_file == null) {
+ channel.terminate(new Exception("Program does not exist"));
+ return;
+ }
+ final IFileSystem fs = channel.getRemoteService(IFileSystem.class);
+ if (fs == null) {
+ channel.terminate(new Exception(
+ "Cannot download program file: target does not provide File System service"));
+ return;
+ }
+ try {
+ final InputStream inp = new FileInputStream(local_file);
+ int flags = IFileSystem.TCF_O_WRITE | IFileSystem.TCF_O_CREAT | IFileSystem.TCF_O_TRUNC;
+ fs.open(remote_file, flags, null, new IFileSystem.DoneOpen() {
+
+ IFileHandle handle;
+ long offset = 0;
+ final Set<IToken> cmds = new HashSet<IToken>();
+ final byte[] buf = new byte[0x1000];
+
+ public void doneOpen(IToken token, FileSystemException error, IFileHandle handle) {
+ this.handle = handle;
+ if (error != null) {
+ TCFLaunch.this.error = new Exception("Cannot download program file", error);
+ fireChanged();
+ done.run();
+ }
+ else {
+ write_next();
+ }
+ }
+
+ private void write_next() {
+ try {
+ while (cmds.size() < 8) {
+ int rd = inp.read(buf);
+ if (rd < 0) {
+ close();
+ break;
+ }
+ cmds.add(fs.write(handle, offset, buf, 0, rd, new IFileSystem.DoneWrite() {
+
+ public void doneWrite(IToken token, FileSystemException error) {
+ cmds.remove(token);
+ if (error != null) channel.terminate(error);
+ else write_next();
+ }
+ }));
+ offset += rd;
+ }
+ }
+ catch (Throwable x) {
+ channel.terminate(x);
+ }
+ }
+
+ private void close() {
+ if (cmds.size() > 0) return;
+ try {
+ inp.close();
+ fs.close(handle, new IFileSystem.DoneClose() {
+
+ public void doneClose(IToken token, FileSystemException error) {
+ if (error != null) channel.terminate(error);
+ else done.run();
+ }
+ });
+ }
+ catch (Throwable x) {
+ channel.terminate(x);
+ }
+ }
+ });
+ }
+ catch (Throwable x) {
+ channel.terminate(x);
+ }
+ }
+
+ private String getProgramPath(String project_name, String local_file) {
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(project_name);
+ IPath program_path = new Path(local_file);
+ if (!program_path.isAbsolute()) {
+ if (project == null || !project.getFile(local_file).exists()) return null;
+ program_path = project.getFile(local_file).getLocation();
+ }
+ return program_path.toOSString();
+ }
+
protected void runShutdownSequence(final Runnable done) {
done.run();
}
diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/launch/LaunchDialogTabGroup.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/launch/LaunchDialogTabGroup.java
index aad3b3e63..999e4ada5 100644
--- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/launch/LaunchDialogTabGroup.java
+++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/launch/LaunchDialogTabGroup.java
@@ -17,7 +17,7 @@ import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
import org.eclipse.tm.internal.tcf.debug.ui.launch.TCFArgumentsTab;
-import org.eclipse.tm.internal.tcf.debug.ui.launch.TCFMainTab;
+import org.eclipse.tm.internal.tcf.debug.ui.launch.TCFTargetTab;
/**
@@ -27,7 +27,7 @@ public class LaunchDialogTabGroup extends AbstractLaunchConfigurationTabGroup {
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
setTabs(new ILaunchConfigurationTab[] {
- new TCFMainTab(),
+ new TCFTargetTab(),
new TCFArgumentsTab(),
new EnvironmentTab(),
new SourceLookupTab(),

Back to the top