| /******************************************************************************* |
| * Copyright (c) 2005, 2009 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| * Remy Chi Jian Suen <remy.suen@gmail.com> |
| * - Bug 214696 Expose WorkingDirectoryBlock as API |
| * - Bug 221973 Make WorkingDirectoryBlock from JDT a Debug API class |
| *******************************************************************************/ |
| package org.eclipse.debug.ui; |
| |
| import java.io.File; |
| |
| import org.eclipse.core.filesystem.URIUtil; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.variables.IStringVariableManager; |
| import org.eclipse.core.variables.VariablesPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.internal.ui.DebugUIMessages; |
| import org.eclipse.debug.internal.ui.SWTFactory; |
| 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.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.DirectoryDialog; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.ContainerSelectionDialog; |
| |
| /** |
| * A control for setting the working directory associated with a launch |
| * configuration. |
| * |
| * @since 3.5 |
| */ |
| public abstract class WorkingDirectoryBlock extends AbstractLaunchConfigurationTab { |
| |
| // Local directory |
| private Button fWorkspaceButton; |
| private Button fFileSystemButton; |
| private Button fVariablesButton; |
| |
| //bug 29565 fix |
| private Button fUseDefaultDirButton = null; |
| private Button fUseOtherDirButton = null; |
| private Text fOtherWorkingText = null; |
| private Text fWorkingDirText; |
| |
| /** |
| * The last launch config this tab was initialized from |
| */ |
| private ILaunchConfiguration fLaunchConfiguration; |
| |
| /** |
| * A listener to update for text changes and widget selection |
| */ |
| private class WidgetListener extends SelectionAdapter implements ModifyListener { |
| public void modifyText(ModifyEvent e) { |
| scheduleUpdateJob(); |
| } |
| public void widgetSelected(SelectionEvent e) { |
| Object source= e.getSource(); |
| if (source == fWorkspaceButton) { |
| handleWorkspaceDirBrowseButtonSelected(); |
| } |
| else if (source == fFileSystemButton) { |
| handleWorkingDirBrowseButtonSelected(); |
| } |
| else if (source == fVariablesButton) { |
| handleWorkingDirVariablesButtonSelected(); |
| } |
| else if(source == fUseDefaultDirButton) { |
| //only perform the action if this is the button that was selected |
| if(fUseDefaultDirButton.getSelection()) { |
| setDefaultWorkingDir(); |
| } |
| } |
| else if(source == fUseOtherDirButton) { |
| //only perform the action if this is the button that was selected |
| if(fUseOtherDirButton.getSelection()) { |
| handleUseOtherWorkingDirButtonSelected(); |
| } |
| } |
| } |
| } |
| |
| private WidgetListener fListener = new WidgetListener(); |
| |
| /** |
| * The name of the launch configuration attribute that will be used to save |
| * the location of the working directory. |
| */ |
| private final String workingDirectoryAttribteName; |
| |
| /** |
| * The help context id to use to connect this working directory block |
| * to the help system. |
| */ |
| private final String helpContextId; |
| |
| /** |
| * Creates a new WorkingDirectoryBlock for setting a working directory. |
| * |
| * @param workingDirectoryAttribteName the name of the launch configuration attribute to set the working directory's location, cannot be <tt>null</tt> |
| */ |
| protected WorkingDirectoryBlock(String workingDirectoryAttribteName) { |
| this(workingDirectoryAttribteName, null); |
| } |
| |
| /** |
| * Creates a new WorkingDirectoryBlock for setting a working directory. |
| * |
| * @param workingDirectoryAttribteName the name of the launch configuration attribute to set the working directory's location, cannot be <tt>null</tt> |
| * @param helpContextId the help context id to use to hook onto the help system |
| */ |
| protected WorkingDirectoryBlock(String workingDirectoryAttribteName, |
| String helpContextId) { |
| Assert.isNotNull(workingDirectoryAttribteName); |
| this.workingDirectoryAttribteName = workingDirectoryAttribteName; |
| this.helpContextId = helpContextId; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) |
| */ |
| public final void createControl(Composite parent) { |
| Font font = parent.getFont(); |
| Group group = SWTFactory.createGroup(parent, DebugUIMessages.WorkingDirectoryBlock_12, 2, 1, GridData.FILL_HORIZONTAL); |
| setControl(group); |
| |
| if (helpContextId != null) { |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(group, helpContextId); |
| } |
| |
| //default choice |
| Composite comp = SWTFactory.createComposite(group, font, 2, 2, GridData.FILL_BOTH, 0, 0); |
| fUseDefaultDirButton = SWTFactory.createRadioButton(comp, DebugUIMessages.WorkingDirectoryBlock_18); |
| fUseDefaultDirButton.addSelectionListener(fListener); |
| fWorkingDirText = SWTFactory.createSingleText(comp, 1); |
| fWorkingDirText.addModifyListener(fListener); |
| fWorkingDirText.setEnabled(false); |
| //user enter choice |
| fUseOtherDirButton = SWTFactory.createRadioButton(comp, DebugUIMessages.WorkingDirectoryBlock_19); |
| fUseOtherDirButton.addSelectionListener(fListener); |
| fOtherWorkingText = SWTFactory.createSingleText(comp, 1); |
| fOtherWorkingText.addModifyListener(fListener); |
| //buttons |
| Composite buttonComp = SWTFactory.createComposite(comp, font, 3, 2, GridData.HORIZONTAL_ALIGN_END); |
| GridLayout ld = (GridLayout)buttonComp.getLayout(); |
| ld.marginHeight = 1; |
| ld.marginWidth = 0; |
| fWorkspaceButton = createPushButton(buttonComp, DebugUIMessages.WorkingDirectoryBlock_0, null); |
| fWorkspaceButton.addSelectionListener(fListener); |
| fFileSystemButton = createPushButton(buttonComp, DebugUIMessages.WorkingDirectoryBlock_1, null); |
| fFileSystemButton.addSelectionListener(fListener); |
| fVariablesButton = createPushButton(buttonComp, DebugUIMessages.WorkingDirectoryBlock_17, null); |
| fVariablesButton.addSelectionListener(fListener); |
| } |
| |
| /** |
| * Show a dialog that lets the user select a working directory |
| */ |
| private void handleWorkingDirBrowseButtonSelected() { |
| DirectoryDialog dialog = new DirectoryDialog(getShell()); |
| dialog.setMessage(DebugUIMessages.WorkingDirectoryBlock_7); |
| String currentWorkingDir = getWorkingDirectoryText(); |
| if (!currentWorkingDir.trim().equals("")) { //$NON-NLS-1$ |
| File path = new File(currentWorkingDir); |
| if (path.exists()) { |
| dialog.setFilterPath(currentWorkingDir); |
| } |
| } |
| String selectedDirectory = dialog.open(); |
| if (selectedDirectory != null) { |
| fOtherWorkingText.setText(selectedDirectory); |
| } |
| } |
| |
| /** |
| * Show a dialog that lets the user select a working directory from |
| * the workspace |
| */ |
| private void handleWorkspaceDirBrowseButtonSelected() { |
| IContainer currentContainer= getContainer(); |
| if (currentContainer == null) { |
| currentContainer = ResourcesPlugin.getWorkspace().getRoot(); |
| } |
| ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), currentContainer, false, DebugUIMessages.WorkingDirectoryBlock_4); |
| dialog.showClosedProjects(false); |
| dialog.open(); |
| Object[] results = dialog.getResult(); |
| if ((results != null) && (results.length > 0) && (results[0] instanceof IPath)) { |
| IPath path = (IPath)results[0]; |
| String containerName = path.makeRelative().toString(); |
| setOtherWorkingDirectoryText("${workspace_loc:" + containerName + "}"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| /** |
| * Returns the selected workspace container,or <code>null</code> |
| */ |
| protected IContainer getContainer() { |
| String path = getWorkingDirectoryText(); |
| if (path.length() > 0) { |
| IResource res = null; |
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
| if (path.startsWith("${workspace_loc:")) { //$NON-NLS-1$ |
| IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); |
| try { |
| path = manager.performStringSubstitution(path, false); |
| IPath uriPath = new Path(path).makeAbsolute(); |
| IContainer[] containers = root.findContainersForLocationURI(URIUtil.toURI(uriPath)); |
| if (containers.length > 0) { |
| res = containers[0]; |
| } |
| } |
| catch (CoreException e) { |
| log(e); |
| } |
| } |
| else { |
| res = root.findMember(path); |
| } |
| if (res instanceof IContainer) { |
| return (IContainer)res; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * The default working dir radio button has been selected. |
| */ |
| private void handleUseDefaultWorkingDirButtonSelected() { |
| fWorkspaceButton.setEnabled(false); |
| fOtherWorkingText.setEnabled(false); |
| fVariablesButton.setEnabled(false); |
| fFileSystemButton.setEnabled(false); |
| fUseOtherDirButton.setSelection(false); |
| } |
| |
| /** |
| * The other working dir radio button has been selected |
| */ |
| private void handleUseOtherWorkingDirButtonSelected() { |
| fOtherWorkingText.setEnabled(true); |
| fWorkspaceButton.setEnabled(true); |
| fVariablesButton.setEnabled(true); |
| fFileSystemButton.setEnabled(true); |
| updateLaunchConfigurationDialog(); |
| } |
| |
| /** |
| * The working dir variables button has been selected |
| */ |
| private void handleWorkingDirVariablesButtonSelected() { |
| StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell()); |
| dialog.open(); |
| String variableText = dialog.getVariableExpression(); |
| if (variableText != null) { |
| fOtherWorkingText.insert(variableText); |
| } |
| } |
| |
| /** |
| * Sets the default working directory. |
| */ |
| protected void setDefaultWorkingDir() { |
| try { |
| ILaunchConfiguration config = getLaunchConfiguration(); |
| if (config != null) { |
| IProject project = getProject(config); |
| if (project != null) { |
| setDefaultWorkingDirectoryText("${workspace_loc:" + project.getFullPath().makeRelative().toOSString() + "}"); //$NON-NLS-1$//$NON-NLS-2$ |
| return; |
| } |
| } |
| } |
| catch (CoreException ce) { |
| log(ce); |
| } |
| setDefaultWorkingDirectoryText(System.getProperty("user.dir")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the project associated with the specified launch configuration or |
| * <code>null</code> if none. |
| * |
| * @param configuration the launch configuration that has been set to this working directory block |
| * @return the project specified by the launch configuration, or <tt>null</tt> if nothing has been set |
| * @throws CoreException if an error occurred while retrieving the project from the launch configuration |
| */ |
| protected abstract IProject getProject(ILaunchConfiguration configuration) throws CoreException; |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration) |
| */ |
| public boolean isValid(ILaunchConfiguration config) { |
| setErrorMessage(null); |
| setMessage(null); |
| // if variables are present, we cannot resolve the directory |
| String workingDirPath = getWorkingDirectoryText(); |
| if (workingDirPath.indexOf("${") >= 0) { //$NON-NLS-1$ |
| IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); |
| try { |
| manager.validateStringVariables(workingDirPath); |
| } |
| catch (CoreException e) { |
| setErrorMessage(e.getMessage()); |
| return false; |
| } |
| } |
| else if (workingDirPath.length() > 0) { |
| IContainer container = getContainer(); |
| if (container == null) { |
| File dir = new File(workingDirPath); |
| if (dir.isDirectory()) { |
| return true; |
| } |
| setErrorMessage(DebugUIMessages.WorkingDirectoryBlock_10); |
| return false; |
| } |
| } else if (workingDirPath.length() == 0) { |
| setErrorMessage(DebugUIMessages.WorkingDirectoryBlock_20); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Sets the default working directory to be used by the launch configuration. |
| * The default implementation has no default working directory. |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| public void setDefaults(ILaunchConfigurationWorkingCopy config) { |
| config.setAttribute(workingDirectoryAttribteName, (String)null); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) |
| */ |
| public void initializeFrom(ILaunchConfiguration configuration) { |
| setLaunchConfiguration(configuration); |
| try { |
| String wd = configuration.getAttribute(workingDirectoryAttribteName, (String)null); |
| setDefaultWorkingDir(); |
| if (wd != null) { |
| setOtherWorkingDirectoryText(wd); |
| } |
| } |
| catch (CoreException e) { |
| setErrorMessage(DebugUIMessages.WorkingDirectoryBlock_Exception_occurred_reading_configuration___15 + e.getStatus().getMessage()); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| public void performApply(ILaunchConfigurationWorkingCopy configuration) { |
| if(fUseDefaultDirButton.getSelection()) { |
| configuration.setAttribute(workingDirectoryAttribteName, (String)null); |
| } |
| else { |
| configuration.setAttribute(workingDirectoryAttribteName, getWorkingDirectoryText()); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName() |
| */ |
| public String getName() { |
| return DebugUIMessages.WorkingDirectoryBlock_Working_Directory_8; |
| } |
| |
| /** |
| * Logs exceptions that have been caught by this working directory block. |
| * Subclasses should reimplement if they wish to monitor such exceptions. |
| * Default implementation does nothing. |
| * @param e the exception to log |
| */ |
| protected void log(CoreException e) { |
| // nothing |
| } |
| |
| /** |
| * Retrieves the path from the text box that has been selected. |
| * @return the working directory the user wishes to use |
| */ |
| protected final String getWorkingDirectoryText() { |
| if(fUseDefaultDirButton.getSelection()) { |
| return fWorkingDirText.getText().trim(); |
| } |
| return fOtherWorkingText.getText().trim(); |
| } |
| |
| /** |
| * Sets the text of the default working directory. |
| * @param dir the directory to set the widget to |
| */ |
| protected final void setDefaultWorkingDirectoryText(String dir) { |
| if(dir != null) { |
| fWorkingDirText.setText(dir); |
| fUseDefaultDirButton.setSelection(true); |
| handleUseDefaultWorkingDirButtonSelected(); |
| } |
| } |
| |
| /** |
| * Sets the directory of the other working directory to be used. |
| * @param dir the directory to set the widget to |
| */ |
| protected final void setOtherWorkingDirectoryText(String dir) { |
| if(dir != null) { |
| fOtherWorkingText.setText(dir); |
| fUseDefaultDirButton.setSelection(false); |
| fUseOtherDirButton.setSelection(true); |
| handleUseOtherWorkingDirButtonSelected(); |
| } |
| } |
| |
| /** |
| * Sets the launch configuration to be used by this working directory block. |
| */ |
| protected void setLaunchConfiguration(ILaunchConfiguration config) { |
| fLaunchConfiguration = config; |
| } |
| |
| /** |
| * Returns the launch configuration that this working directory block is using. |
| * @return this working directory block's launch configuration |
| */ |
| protected ILaunchConfiguration getLaunchConfiguration() { |
| return fLaunchConfiguration; |
| } |
| |
| /** |
| * Allows this entire block to be enabled/disabled |
| * @param enabled whether to enable it or not |
| */ |
| public final void setEnabled(boolean enabled) { |
| fUseDefaultDirButton.setEnabled(enabled); |
| fUseOtherDirButton.setEnabled(enabled); |
| if(fOtherWorkingText.isEnabled()) { |
| fOtherWorkingText.setEnabled(enabled); |
| fWorkspaceButton.setEnabled(enabled); |
| fVariablesButton.setEnabled(enabled); |
| fFileSystemButton.setEnabled(enabled); |
| } |
| // in the case where the 'other' text is selected and we want to enable |
| if(fUseOtherDirButton.getSelection() && enabled == true) { |
| fOtherWorkingText.setEnabled(enabled); |
| } |
| } |
| |
| } |
| |