| /******************************************************************************* |
| * Copyright (c) 2005, 2017 IBM Corporation and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.internal.debug.ui.launcher; |
| |
| import java.io.File; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.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.ui.StringVariableSelectionDialog; |
| import org.eclipse.dltk.compiler.util.Util; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.environment.EnvironmentManager; |
| import org.eclipse.dltk.core.environment.IEnvironment; |
| import org.eclipse.dltk.debug.ui.launchConfigurations.CommonScriptLaunchTab; |
| import org.eclipse.dltk.debug.ui.messages.ScriptLaunchMessages; |
| import org.eclipse.dltk.internal.launching.DLTKLaunchingPlugin; |
| import org.eclipse.dltk.launching.ScriptLaunchConfigurationConstants; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| 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.dialogs.ContainerSelectionDialog; |
| |
| /** |
| * A control for setting the working directory associated with a launch |
| * configuration. |
| */ |
| public class WorkingDirectoryBlock extends CommonScriptLaunchTab { |
| |
| // 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; |
| |
| /** |
| * A listener to update for text changes and widget selection |
| */ |
| private class WidgetListener extends SelectionAdapter |
| implements ModifyListener { |
| @Override |
| public void modifyText(ModifyEvent e) { |
| updateLaunchConfigurationDialog(); |
| }// end modifyText |
| |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| Object source = e.getSource(); |
| if (source == fWorkspaceButton) { |
| handleWorkspaceDirBrowseButtonSelected(); |
| } // end if |
| else if (source == fFileSystemButton) { |
| handleWorkingDirBrowseButtonSelected(); |
| } // end if |
| else if (source == fVariablesButton) { |
| handleWorkingDirVariablesButtonSelected(); |
| } // end if |
| else if (source == fUseDefaultDirButton) { |
| // only perform the action if this is the button that was |
| // selected |
| if (fUseDefaultDirButton.getSelection()) { |
| setDefaultWorkingDir(); |
| } // end if |
| } // end if |
| else if (source == fUseOtherDirButton) { |
| // only perform the action if this is the button that was |
| // selected |
| if (fUseOtherDirButton.getSelection()) { |
| handleUseOtherWorkingDirButtonSelected(); |
| } // end if |
| } // end if |
| }// end widgetSelected |
| }// end WidgetListener class |
| |
| private WidgetListener fListener = new WidgetListener(); |
| |
| @Override |
| public void createControl(Composite parent) { |
| Font font = parent.getFont(); |
| |
| Group group = new Group(parent, SWT.NONE); |
| // PlatformUI.getWorkbench().getHelpSystem().setHelp(group, |
| // IScriptDebugHelpContextIds.WORKING_DIRECTORY_BLOCK); |
| GridLayout workingDirLayout = new GridLayout(); |
| workingDirLayout.numColumns = 2; |
| workingDirLayout.makeColumnsEqualWidth = false; |
| group.setLayout(workingDirLayout); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| group.setLayoutData(gd); |
| group.setFont(font); |
| setControl(group); |
| |
| group.setText(ScriptLaunchMessages.WorkingDirectoryBlock_12); |
| |
| fUseDefaultDirButton = new Button(group, SWT.RADIO); |
| fUseDefaultDirButton |
| .setText(ScriptLaunchMessages.WorkingDirectoryBlock_18); |
| fUseDefaultDirButton.setFont(font); |
| fUseDefaultDirButton.addSelectionListener(fListener); |
| fWorkingDirText = new Text(group, SWT.SINGLE | SWT.BORDER); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| fWorkingDirText.setLayoutData(gd); |
| fWorkingDirText.setFont(font); |
| fWorkingDirText.addModifyListener(fListener); |
| fWorkingDirText.setEnabled(false); |
| |
| fUseOtherDirButton = new Button(group, SWT.RADIO); |
| fUseOtherDirButton |
| .setText(ScriptLaunchMessages.WorkingDirectoryBlock_19); |
| fUseOtherDirButton.setFont(font); |
| fUseOtherDirButton.addSelectionListener(fListener); |
| fOtherWorkingText = new Text(group, SWT.SINGLE | SWT.BORDER); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| fOtherWorkingText.setLayoutData(gd); |
| fOtherWorkingText.setFont(font); |
| fOtherWorkingText.addModifyListener(fListener); |
| |
| Composite buttonComp = new Composite(group, SWT.NONE); |
| GridLayout layout = new GridLayout(3, false); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| buttonComp.setLayout(layout); |
| gd = new GridData(GridData.HORIZONTAL_ALIGN_END); |
| gd.horizontalSpan = 2; |
| buttonComp.setLayoutData(gd); |
| buttonComp.setFont(font); |
| fWorkspaceButton = createPushButton(buttonComp, |
| ScriptLaunchMessages.WorkingDirectoryBlock_0, null); |
| fWorkspaceButton.addSelectionListener(fListener); |
| |
| fFileSystemButton = createPushButton(buttonComp, |
| ScriptLaunchMessages.WorkingDirectoryBlock_1, null); |
| fFileSystemButton.addSelectionListener(fListener); |
| |
| fVariablesButton = createPushButton(buttonComp, |
| ScriptLaunchMessages.WorkingDirectoryBlock_17, null); |
| fVariablesButton.addSelectionListener(fListener); |
| } |
| |
| @Override |
| public void dispose() { |
| } |
| |
| /** |
| * Show a dialog that lets the user select a working directory |
| */ |
| private void handleWorkingDirBrowseButtonSelected() { |
| DirectoryDialog dialog = new DirectoryDialog(getShell()); |
| dialog.setMessage(ScriptLaunchMessages.WorkingDirectoryBlock_7); |
| String currentWorkingDir = getWorkingDirectoryText(); |
| if (!currentWorkingDir.trim().equals("")) { //$NON-NLS-1$ |
| File path = new File(currentWorkingDir); |
| if (path.exists()) { |
| dialog.setFilterPath(currentWorkingDir); |
| } // end if |
| } // end if |
| String selectedDirectory = dialog.open(); |
| if (selectedDirectory != null) { |
| fOtherWorkingText.setText(selectedDirectory); |
| } // end if |
| }// end handleQWrokingDirBrowseBUttonSelected |
| |
| /** |
| * 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(); |
| } // end if |
| ContainerSelectionDialog dialog = new ContainerSelectionDialog( |
| getShell(), currentContainer, false, |
| ScriptLaunchMessages.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$ |
| } // end if |
| }// end handleWorkspaceDirBrowseButtonSelected |
| |
| /** |
| * 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); |
| IContainer[] containers = root |
| .findContainersForLocation(new Path(path)); |
| if (containers.length > 0) { |
| res = containers[0]; |
| } // end if |
| } // end try |
| catch (CoreException e) { |
| } |
| } // end if |
| else { |
| res = root.findMember(path); |
| } // end else |
| if (res instanceof IContainer) { |
| return (IContainer) res; |
| } // end if |
| } // end if |
| return null; |
| }// end getContainer |
| |
| /** |
| * 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); |
| } // end if |
| }// end handleWorkingDirVariablesButtonSelected |
| |
| /** |
| * Convenience method to get the workspace root. |
| */ |
| protected IWorkspaceRoot getWorkspaceRoot() { |
| return ResourcesPlugin.getWorkspace().getRoot(); |
| } |
| |
| private static final String DEFAULT_WORKING_DIRECTORY = "${resource_loc}/../"; //$NON-NLS-1$ |
| |
| /** |
| * Sets the default working directory |
| */ |
| protected void setDefaultWorkingDir() { |
| try { |
| ILaunchConfiguration config = getCurrentLaunchConfiguration(); |
| if (config != null) { |
| IScriptProject project = getProject(config); |
| if (project != null) { |
| String path = DEFAULT_WORKING_DIRECTORY; |
| IEnvironment environment = EnvironmentManager |
| .getEnvironment(project); |
| if (environment != null) { |
| path = path.replace('/', |
| environment.getSeparatorChar()); |
| } |
| setDefaultWorkingDirectoryText(path); |
| return; |
| } |
| } |
| } catch (CoreException 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 |
| * @return |
| * @throws CoreException |
| */ |
| protected IScriptProject getProject(ILaunchConfiguration configuration) |
| throws CoreException { |
| String projectName = configuration.getAttribute( |
| ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME, |
| Util.EMPTY_STRING); |
| if (!projectName.equals(Util.EMPTY_STRING)) { |
| return DLTKCore.create(getWorkspaceRoot()) |
| .getScriptProject(projectName); |
| } |
| return null; |
| } |
| |
| @Override |
| 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); |
| } // end try |
| catch (CoreException e) { |
| setErrorMessage(e.getMessage()); |
| return false; |
| } // end catch |
| } // end if |
| else if (workingDirPath.length() > 0) { |
| IContainer container = getContainer(); |
| if (container == null) { |
| File dir = new File(workingDirPath); |
| if (dir.isDirectory()) { |
| return true; |
| } // end if |
| setErrorMessage(ScriptLaunchMessages.WorkingDirectoryBlock_10); |
| return false; |
| } // end if |
| } else if (workingDirPath.length() == 0) { |
| setErrorMessage(ScriptLaunchMessages.WorkingDirectoryBlock_20); |
| } |
| return true; |
| }// end isValid |
| |
| /** |
| * Defaults are empty. |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse. |
| * debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| @Override |
| public void setDefaults(ILaunchConfigurationWorkingCopy config) { |
| config.setAttribute( |
| ScriptLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, |
| (String) null); |
| } |
| |
| @Override |
| public void initializeFrom(ILaunchConfiguration configuration) { |
| super.initializeFrom(configuration); |
| try { |
| String wd = configuration.getAttribute( |
| ScriptLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, |
| (String) null); |
| setDefaultWorkingDir(); |
| if (wd != null) { |
| setOtherWorkingDirectoryText(wd); |
| } // end else |
| } // end try |
| catch (CoreException e) { |
| setErrorMessage(NLS.bind( |
| ScriptLaunchMessages.ArgumentsTab_Exception_occurred_reading_configuration___15, |
| e.getStatus().getMessage())); |
| DLTKLaunchingPlugin.log(e); |
| } // end catch |
| } |
| |
| @Override |
| public void performApply(ILaunchConfigurationWorkingCopy configuration) { |
| if (fUseDefaultDirButton.getSelection()) { |
| configuration.setAttribute( |
| ScriptLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, |
| (String) null); |
| } // end if |
| else { |
| configuration.setAttribute( |
| ScriptLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, |
| getWorkingDirectoryText()); |
| } // end else |
| }// end performApply |
| |
| @Override |
| public String getName() { |
| return ScriptLaunchMessages.WorkingDirectoryBlock_Working_Directory_8; |
| }// end getName |
| |
| /** |
| * gets the path from the text box that is selected |
| * |
| * @return the working directory the user wishes to use |
| * |
| */ |
| protected String getWorkingDirectoryText() { |
| if (fUseDefaultDirButton.getSelection()) { |
| return fWorkingDirText.getText().trim(); |
| } // end if |
| return fOtherWorkingText.getText().trim(); |
| }// end getWorkingDirectoryPath |
| |
| /** |
| * sets the default working directory text |
| * |
| * @param dir |
| * the dir to set the widget to |
| * |
| */ |
| protected void setDefaultWorkingDirectoryText(String dir) { |
| if (dir != null) { |
| fWorkingDirText.setText(dir); |
| fUseDefaultDirButton.setSelection(true); |
| handleUseDefaultWorkingDirButtonSelected(); |
| } // end if |
| }// setDefaultWorkingDirectoryText |
| |
| /** |
| * sets the other dir text |
| * |
| * @param dir |
| * the new text |
| * |
| */ |
| protected void setOtherWorkingDirectoryText(String dir) { |
| if (dir != null) { |
| fOtherWorkingText.setText(dir); |
| fUseDefaultDirButton.setSelection(false); |
| fUseOtherDirButton.setSelection(true); |
| handleUseOtherWorkingDirButtonSelected(); |
| } // end if |
| }// end setOtherWorkingDirectoryText |
| |
| /** |
| * Allows this entire block to be enabled/disabled |
| * |
| * @param enabled |
| * whether to enable it or not |
| */ |
| protected 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); |
| } // end if |
| // in the case where the' other' text is selected and we want to |
| // enable |
| if (fUseOtherDirButton.getSelection() && enabled == true) { |
| fOtherWorkingText.setEnabled(enabled); |
| } // end if |
| }// end setEnabled |
| |
| }// end class |