1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-03 07:05:24 +02:00

Bug 309899 - New local terminal launch configurations should have reasonable default values

This commit is contained in:
Martin Oberhuber 2010-05-20 02:19:45 +00:00
parent d03e95d0fa
commit c8b9148f5b
11 changed files with 200 additions and 27 deletions

View file

@ -7,7 +7,7 @@ feature@org.eclipse.tm.terminal.telnet=v201005032000,:pserver:anonymous:none@dev
feature@org.eclipse.tm.terminal.test=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.test-feature
feature@org.eclipse.tm.terminal.view=v201005032000,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.view-feature
plugin@org.eclipse.tm.terminal=v201005200200,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal
plugin@org.eclipse.tm.terminal.local=v201005032000,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.local
plugin@org.eclipse.tm.terminal.local=v201005200200,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.local
plugin@org.eclipse.tm.terminal.serial=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.serial
plugin@org.eclipse.tm.terminal.ssh=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.ssh
plugin@org.eclipse.tm.terminal.telnet=v200909160005,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.telnet

View file

@ -13,7 +13,12 @@
package org.eclipse.tm.internal.terminal.local;
import java.io.OutputStream;
import java.text.Format;
import java.text.MessageFormat;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
@ -26,6 +31,9 @@ import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities;
import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessFactory;
import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessRegistry;
@ -42,7 +50,7 @@ import org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnect
* <code>vi</code> editor).
*
* @author Mirko Raner
* @version $Revision: 1.4 $
* @version $Revision: 1.1 $
*/
public class LocalTerminalConnector extends TerminalConnectorImpl
implements IDebugEventSetListener {
@ -171,22 +179,48 @@ implements IDebugEventSetListener {
control.setState(TerminalState.CONNECTING);
ILaunchConfigurationWorkingCopy workingCopy = null;
ILaunchConfiguration configuration = null;
String configurationName = null;
try {
String configurationName = settings.getLaunchConfigurationName();
configurationName = settings.getLaunchConfigurationName();
configuration = LocalTerminalUtilities.findLaunchConfiguration(configurationName);
}
catch (CoreException exception) {
// Always set the the process factory ID and enable console output (there is no need
// to restore these attributes afterwards; disabling console output does not make
// sense for terminal launches and will be overridden when the configuration is
// actually launched):
//
Shell shell = Display.getDefault().getActiveShell();
String title = LocalTerminalMessages.errorTitleCouldNotConnectToTerminal;
Format text;
text = new MessageFormat(LocalTerminalMessages.errorLaunchConfigurationNoLongerExists);
String message = text.format(new Object[] {configurationName});
IStatus status = new Status(IStatus.ERROR, LocalTerminalActivator.PLUGIN_ID, message);
ErrorDialog.openError(shell, title, null, status);
control.setState(TerminalState.CLOSED);
return;
}
try {
String oldFactoryID = configuration.getAttribute(ATTR_PROCESS_FACTORY_ID, (String)null);
workingCopy = configuration.getWorkingCopy();
workingCopy.setAttribute(ATTR_CAPTURE_OUTPUT, true);
workingCopy.setAttribute(ATTR_CAPTURE_IN_CONSOLE, true);
workingCopy.setAttribute(ATTR_PROCESS_FACTORY_ID, LocalTerminalProcessFactory.ID);
configuration = workingCopy.doSave();
launch = configuration.launch(ILaunchManager.RUN_MODE, null);
try {
launch = configuration.launch(ILaunchManager.RUN_MODE, null);
}
finally {
// The process factory ID is used to distinguish between launches that originate
// from the terminal connector and launches that originate from the launch dialog.
// After launching, the original ID is restored so that the launch is not mistaken
// as originating from the terminal connector UI when it is launched via the launch
// dialog the next time:
//
workingCopy = configuration.getWorkingCopy();
workingCopy.setAttribute(ATTR_PROCESS_FACTORY_ID, oldFactoryID);
workingCopy.doSave();
}
// To prevent a console from being allocated, the launch will actually not contain a
// reference to the runtime process. The process has to be obtained from the
@ -257,9 +291,9 @@ implements IDebugEventSetListener {
//
LocalTerminalProcessRegistry.addProcessBackToFinishedLaunch(launch);
// Now, terminate the process if it hasn't been terminated already:
// Now, terminate the process if it was ever started and hasn't been terminated already:
//
if (launch.canTerminate()) {
if (launch != null && launch.canTerminate()) {
launch.terminate();
//

View file

@ -51,7 +51,7 @@ public class LocalTerminalLaunchListProvider implements IStructuredContentProvid
public Object[] getElements(Object input) {
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = LocalTerminalUtilities.PROGRAM_LAUNCH_TYPE;
ILaunchConfigurationType type = LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE;
ILaunchConfiguration[] configurations = null;
try {

View file

@ -18,7 +18,7 @@ import org.eclipse.osgi.util.NLS;
* messages used by the Local Terminal Connector.
*
* @author Mirko Raner
* @version $Revision: 1.3 $
* @version $Revision: 1.1 $
*/
public class LocalTerminalMessages extends NLS {
@ -80,6 +80,15 @@ public class LocalTerminalMessages extends NLS {
/** The error message for an invalid working directory location. */
public static String invalidWorkingDirectory;
/** The error message for attempting to directly launch a Terminal launch configuration. */
public static String errorDirectLaunch;
/** The error message for attempting to launch a no longer existing launch configuration. */
public static String errorLaunchConfigurationNoLongerExists;
/** The error dialog title for failed terminal connections. */
public static String errorTitleCouldNotConnectToTerminal;
/** The title string of the warning displayed when terminal launches are still running. */
public static String warningTitleTerminalsStillRunning;

View file

@ -28,6 +28,13 @@ locationNotSpecified=Executable location was not specified in configuration ''{0
invalidLocation=Executable does not exist for the external tool named ''{0}''
invalidWorkingDirectory=The path {0} is not a directory and cannot be used as working directory \
for ''{1}''
errorDirectLaunch=Terminal launch configurations can only be launched from the Terminal view. \
Please open the Terminal view and click the view's Settings button to select and launch a local \
Terminal.
errorLaunchConfigurationNoLongerExists=The launch configuration ''{0}'' that is selected in the \
Terminal Settings does no longer exist. Please open the Settings dialog to select a valid launch \
configuration.
errorTitleCouldNotConnectToTerminal=Could not connect to Terminal
warningTitleTerminalsStillRunning=Warning: Terminals with active processes are still running
warningMessageTerminalsStillRunning=The workbench is about to be shut down even though one or more \
terminals with active processes are still running. You may abort the shut-down of the workbench \

View file

@ -37,6 +37,7 @@ import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities;
import org.eclipse.tm.internal.terminal.local.ui.DependentHeightComposite;
import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage;
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
@ -46,7 +47,7 @@ import org.eclipse.tm.internal.terminal.provisional.api.Logger;
* local program connections.
*
* @author Mirko Raner
* @version $Revision: 1.4 $
* @version $Revision: 1.1 $
*/
public class LocalTerminalSettingsPage
implements ISettingsPage, ISelectionChangedListener, SelectionListener {
@ -78,6 +79,8 @@ implements ISettingsPage, ISelectionChangedListener, SelectionListener {
*/
public void createControl(Composite parent) {
ILaunchConfiguration defaultConfiguration;
defaultConfiguration = LocalTerminalLaunchUtilities.createDefaultLaunchConfiguration();
Composite enclosing = parent.getParent();
Layout enclosingLayout = enclosing.getLayout();
int extra = 0;
@ -127,6 +130,13 @@ implements ISettingsPage, ISelectionChangedListener, SelectionListener {
// in having it be a part of the ISettingsPage interface
//
loadSettings();
if (defaultConfiguration != null) {
// If there is only one configuration (the default one), then make sure it gets
// selected:
//
viewer.setSelection(new StructuredSelection(defaultConfiguration), true);
}
}
/**
@ -229,8 +239,8 @@ implements ISettingsPage, ISelectionChangedListener, SelectionListener {
ILaunchConfigurationWorkingCopy newlyCreatedConfiguration;
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
String baseName = LocalTerminalMessages.newTerminalLaunchName;
String uniqueName = launchManager.generateUniqueLaunchConfigurationNameFrom(baseName);
ILaunchConfigurationType type = LocalTerminalUtilities.PROGRAM_LAUNCH_TYPE;
String uniqueName = launchManager.generateLaunchConfigurationName(baseName);
ILaunchConfigurationType type = LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE;
try {
newlyCreatedConfiguration = type.newInstance(null, uniqueName);

View file

@ -28,7 +28,7 @@ import org.eclipse.tm.internal.terminal.provisional.api.Logger;
* methods.
*
* @author Mirko Raner
* @version $Revision: 1.3 $
* @version $Revision: 1.1 $
*/
public class LocalTerminalUtilities {
@ -56,10 +56,10 @@ public class LocalTerminalUtilities {
public final static ILaunchManager LAUNCH_MANAGER = DebugPlugin.getDefault().getLaunchManager();
/**
* The {@link ILaunchConfigurationType} for "Program" launches (in the "External Tools"
* The {@link ILaunchConfigurationType} for "Terminal" launches (in the "External Tools"
* category).
*/
public final static ILaunchConfigurationType PROGRAM_LAUNCH_TYPE =
public final static ILaunchConfigurationType TERMINAL_LAUNCH_TYPE =
LAUNCH_MANAGER.getLaunchConfigurationType(LOCAL_TERMINAL);
/**
@ -74,7 +74,7 @@ public class LocalTerminalUtilities {
ILaunchConfiguration[] configuration;
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
configuration = manager.getLaunchConfigurations(LocalTerminalUtilities.PROGRAM_LAUNCH_TYPE);
configuration = manager.getLaunchConfigurations(LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE);
int numberOfConfigurations = configuration.length;
for (int index = 0; index < numberOfConfigurations; index++) {

View file

@ -32,6 +32,7 @@ import org.eclipse.osgi.util.NLS;
import org.eclipse.tm.internal.terminal.local.LocalTerminalActivator;
import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages;
import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities;
import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessFactory;
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
import org.eclipse.ui.PlatformUI;
@ -43,7 +44,7 @@ import org.eclipse.ui.PlatformUI;
* {@link ProcessFactory}, which allows the process to run with a pseudo-terminal ({@link PTY}).
*
* @author Mirko Raner and others
* @version $Revision: 1.1 $
* @version $Revision: 1.2 $
*/
public class LocalTerminalLaunchDelegate extends LaunchConfigurationDelegate {
@ -80,6 +81,20 @@ public class LocalTerminalLaunchDelegate extends LaunchConfigurationDelegate {
public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch,
IProgressMonitor progressMonitor) throws CoreException {
String processFactoryID;
processFactoryID = configuration.getAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, EMPTY);
if (!LocalTerminalProcessFactory.ID.equals(processFactoryID)) {
// This launch was not launched via the terminal connector UI but via the launch dialog;
// the launch needs to be explicitly connected to a terminal (otherwise it will appear
// in the regular console), so launching from the launch dialog or from the launch
// history is not supported right now.
//
String message = LocalTerminalMessages.errorDirectLaunch;
IStatus status = new Status(IStatus.ERROR, LocalTerminalActivator.PLUGIN_ID, message);
throw new CoreException(status);
}
// Extract all relevant information from the ILaunchConfiguration; the original
// ProgramLaunchDelegate class checks for cancellation again and again after each step,
// which is a somewhat suspect pattern; however, for now, LocalTerminalLaunchDelegate

View file

@ -16,16 +16,20 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.Image;
import org.eclipse.tm.internal.terminal.local.LocalTerminalActivator;
import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages;
import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities;
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
/**
@ -35,7 +39,7 @@ import org.eclipse.tm.internal.terminal.provisional.api.Logger;
* because the original class is not part of the public API of its plug-in.
*
* @author Mirko Raner and others
* @version $Revision: 1.2 $
* @version $Revision: 1.1 $
*/
public class LocalTerminalLaunchUtilities {
@ -176,6 +180,84 @@ public class LocalTerminalLaunchUtilities {
return null;
}
/**
* Creates an initial default launch configuration for starting a shell if no terminal/program
* launch configurations are defined yet.
*
* @return new {@link ILaunchConfiguration}, or {@code null} if there were already some
* terminal/program launch configurations defined
*/
public static ILaunchConfiguration createDefaultLaunchConfiguration() {
ILaunchConfiguration[] configs;
ILaunchManager manager = LocalTerminalUtilities.LAUNCH_MANAGER;
try {
configs = manager.getLaunchConfigurations(LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE);
if (configs == null || configs.length == 0) {
// Create a default launch configuration only if there aren't any terminal launch
// configurations defined at all:
//
ILaunchConfigurationWorkingCopy workingCopy;
workingCopy = createNewLaunchConfigurationWorkingCopy();
return workingCopy.doSave();
}
}
catch (CoreException exception)
{
exception.printStackTrace(); // TODO: implement proper exception handling
}
return null;
}
/**
* Creates an {@link ILaunchConfigurationWorkingCopy} that uses the default shell as its
* executable and the user's home directory as the working directory.
*
* @return an unsaved {@link ILaunchConfigurationWorkingCopy}
* @throws CoreException if the {@link ILaunchConfigurationWorkingCopy} could not be
* instantiated
* @see #getDefaultShell()
*/
public static ILaunchConfigurationWorkingCopy createNewLaunchConfigurationWorkingCopy()
throws CoreException {
ILaunchConfigurationWorkingCopy workingCopy;
ILaunchManager manager = LocalTerminalUtilities.LAUNCH_MANAGER;
String userHome = System.getProperty("user.home", "/"); //$NON-NLS-1$//$NON-NLS-2$
String name = manager.generateLaunchConfigurationName("Terminal"); //$NON-NLS-1$
workingCopy = LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE.newInstance(null, name);
workingCopy.setAttribute(ATTR_LOCATION, getDefaultShell().getAbsolutePath());
workingCopy.setAttribute(ATTR_WORKING_DIRECTORY, userHome);
return workingCopy;
}
/**
* Returns the system's default shell. First, this method will read the value of the environment
* variable {@code SHELL}. If that variable is not set, it will default to {@code cmd.exe} on
* Windows systems, and to {@code /bin/sh} on all other systems.
*
* @return a {@link File} pointing to the default shell (the underlying file is not guaranteed
* to exist in the file system)
*/
public static File getDefaultShell() {
String shell = System.getenv("SHELL"); //$NON-NLS-1$
if (shell == null) {
if (Platform.OS_WIN32.equals(Platform.getOS())) {
shell = "C:\\Windows\\System32\\cmd.exe"; //$NON-NLS-1$
}
else {
shell = "/bin/sh"; //$NON-NLS-1$
}
}
return new File(shell);
}
//------------------------------------- PRIVATE SECTION --------------------------------------//
private static IStringVariableManager getStringVariableManager() {

View file

@ -34,12 +34,10 @@ import org.eclipse.tm.internal.terminal.provisional.api.Logger;
* @author Mirko Raner
* @version $Revision: 1.1 $
**/
public class LocalTerminalLaunchTabGroup extends AbstractLaunchConfigurationTabGroup
implements IDebugUIConstants {
public class LocalTerminalLaunchTabGroup extends AbstractLaunchConfigurationTabGroup {
private final static String ID = "id"; //$NON-NLS-1$
private final static String CLASS = "class"; //$NON-NLS-1$
private final static String LC_TAB_GROUPS = EXTENSION_POINT_LAUNCH_CONFIGURATION_TAB_GROUPS;
private final static String PROGRAM_TAB_GROUP =
"org.eclipse.ui.externaltools.launchConfigurationTabGroup.program"; //$NON-NLS-1$
@ -81,7 +79,8 @@ implements IDebugUIConstants {
//
IConfigurationElement[] element;
IExtensionRegistry registry = Platform.getExtensionRegistry();
element = registry.getConfigurationElementsFor(IDebugUIConstants.PLUGIN_ID, LC_TAB_GROUPS);
final String TAB_GROUPS = IDebugUIConstants.EXTENSION_POINT_LAUNCH_CONFIGURATION_TAB_GROUPS;
element = registry.getConfigurationElementsFor(IDebugUIConstants.PLUGIN_ID, TAB_GROUPS);
int numberOfElements = element.length;
for (int index = 0; index < numberOfElements; index++) {

View file

@ -38,7 +38,7 @@ import org.eclipse.tm.internal.terminal.provisional.api.Logger;
* and the line separator string.
*
* @author Mirko Raner
* @version $Revision: 1.2 $
* @version $Revision: 1.1 $
**/
public class LocalTerminalSettingsTab extends AbstractLaunchConfigurationTab
implements SelectionListener {
@ -230,6 +230,23 @@ implements SelectionListener {
configuration.setAttribute(LocalTerminalLaunchUtilities.ATTR_LINE_SEPARATOR, NULL);
}
/**
* Prevents Terminal launch configurations from being started directly from the launch
* configuration dialog. The <b>Run</b> button in the dialog will only be enabled if all tabs
* consider a launch configuration valid.
*
* TODO: previously used launches can still be launched via the launch history
* (see {@code ExternalToolMenuDelegate#fillMenu(Menu)})
*
* @param configuration the {@link ILaunchConfiguration}
* @return always {@code false}
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(ILaunchConfiguration)
*/
public boolean isValid(ILaunchConfiguration configuration) {
return false;
}
/**
* Handles selection of any of the buttons in the tab.
*