| /******************************************************************************* |
| * Copyright (c) 2000, 2018 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 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.internal.debug.ui.interpreters; |
| |
| import java.io.File; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.internal.ui.DebugPluginImages; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsMessages; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.dltk.core.environment.IEnvironment; |
| import org.eclipse.dltk.core.environment.IExecutionEnvironment; |
| import org.eclipse.dltk.core.environment.IFileHandle; |
| import org.eclipse.dltk.launching.EnvironmentVariable; |
| import org.eclipse.dltk.launching.IInterpreterInstall; |
| import org.eclipse.dltk.launching.IInterpreterInstallType; |
| import org.eclipse.dltk.ui.dialogs.MultipleInputDialog; |
| import org.eclipse.jface.viewers.IBaseLabelProvider; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Image; |
| 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.Control; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.MessageBox; |
| import org.eclipse.ui.dialogs.ListSelectionDialog; |
| |
| /** |
| * Control used to edit the environment variables associated with a Interpreter |
| * install |
| */ |
| @SuppressWarnings("restriction") |
| public abstract class AbstractInterpreterEnvironmentVariablesBlock |
| implements SelectionListener, ISelectionChangedListener { |
| |
| private static final String VALUE_LABEL = InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_value; |
| |
| private static final String NAME_LABEL = InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_name; |
| |
| protected boolean fInCallback = false; |
| protected IInterpreterInstall fInterpreterInstall; |
| protected IInterpreterInstallType fInterpreterInstallType; |
| |
| // widgets |
| protected EnvironmentVariableContentProvider fEnvironmentVariablesContentProvider; |
| protected TreeViewer fVariablesViewer; |
| private Button fRemoveButton; |
| private Button fAddExistedButton; |
| private Button fAddButton; |
| private Button fEditButton; |
| private Button fImportButton; |
| private Button fExportButton; |
| |
| protected AddScriptInterpreterDialog fDialog; |
| |
| protected AbstractInterpreterEnvironmentVariablesBlock( |
| AddScriptInterpreterDialog dialog) { |
| this.fDialog = dialog; |
| } |
| |
| /** |
| * Creates and returns the source lookup control. |
| * |
| * @param parent |
| * the parent widget of this control |
| */ |
| public Control createControl(Composite parent) { |
| Composite comp = new Composite(parent, SWT.NONE); |
| GridLayout topLayout = new GridLayout(); |
| topLayout.numColumns = 2; |
| topLayout.marginHeight = 0; |
| topLayout.marginWidth = 0; |
| comp.setLayout(topLayout); |
| GridData gd = new GridData(GridData.FILL_BOTH); |
| comp.setLayoutData(gd); |
| createControlsIn(comp); |
| return comp; |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public void createControlsIn(Composite comp) { |
| fVariablesViewer = new TreeViewer(comp); |
| GridData gd = new GridData(GridData.FILL_BOTH); |
| gd.heightHint = 6; |
| fVariablesViewer.getControl().setLayoutData(gd); |
| fEnvironmentVariablesContentProvider = new EnvironmentVariableContentProvider(); |
| fVariablesViewer |
| .setContentProvider(fEnvironmentVariablesContentProvider); |
| fVariablesViewer.setLabelProvider(getLabelProvider()); |
| fVariablesViewer.setInput(this); |
| fVariablesViewer.addSelectionChangedListener(this); |
| |
| Composite pathButtonComp = new Composite(comp, SWT.NONE); |
| GridLayout pathButtonLayout = new GridLayout(); |
| pathButtonLayout.marginHeight = 0; |
| pathButtonLayout.marginWidth = 0; |
| pathButtonComp.setLayout(pathButtonLayout); |
| gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING |
| | GridData.HORIZONTAL_ALIGN_FILL); |
| pathButtonComp.setLayoutData(gd); |
| |
| fAddButton = createPushButton(pathButtonComp, |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_add); |
| fAddButton.addSelectionListener(this); |
| |
| fAddExistedButton = createPushButton(pathButtonComp, |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_addFromEnvironment); |
| fAddExistedButton.addSelectionListener(this); |
| fEditButton = createPushButton(pathButtonComp, |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_edit); |
| fEditButton.addSelectionListener(this); |
| |
| fRemoveButton = createPushButton(pathButtonComp, |
| InterpretersMessages.InterpreterLibraryBlock_6); |
| fRemoveButton.addSelectionListener(this); |
| |
| fImportButton = createPushButton(pathButtonComp, |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_import); |
| fImportButton.addSelectionListener(this); |
| |
| fExportButton = createPushButton(pathButtonComp, |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_export); |
| fExportButton.addSelectionListener(this); |
| } |
| |
| /** |
| * The "default" button has been toggled |
| */ |
| public void restoreDefaultVariables() { |
| fEnvironmentVariablesContentProvider |
| .setVariables(new EnvironmentVariable[0]); |
| update(); |
| } |
| |
| /** |
| * Creates and returns a button |
| * |
| * @param parent |
| * parent widget |
| * @param label |
| * label |
| * @return Button |
| */ |
| protected Button createPushButton(Composite parent, String label) { |
| Button button = new Button(parent, SWT.PUSH); |
| button.setFont(parent.getFont()); |
| button.setText(label); |
| setButtonLayoutData(button); |
| return button; |
| } |
| |
| /** |
| * Create some empty space |
| */ |
| protected void createVerticalSpacer(Composite comp, int colSpan) { |
| Label label = new Label(comp, SWT.NONE); |
| GridData gd = new GridData(); |
| gd.horizontalSpan = colSpan; |
| label.setLayoutData(gd); |
| } |
| |
| /** |
| * Updates buttons and status based on current libraries |
| */ |
| public void update() { |
| updateButtons(); |
| IStatus status = Status.OK_STATUS; |
| EnvironmentVariable[] standins = fEnvironmentVariablesContentProvider |
| .getStandins(); |
| for (int i = 0; i < standins.length; i++) { |
| IStatus st = standins[i].validate(); |
| if (!st.isOK()) { |
| status = st; |
| break; |
| } |
| } |
| updateDialogStatus(status); |
| } |
| |
| /** |
| * Saves settings in the given working copy |
| */ |
| public void performApply(IInterpreterInstall install) { |
| EnvironmentVariable[] libs = fEnvironmentVariablesContentProvider |
| .getVariables(); |
| install.setEnvironmentVariables(libs); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public EnvironmentVariable[] getEnvironmentVariables() { |
| EnvironmentVariable[] libs = fEnvironmentVariablesContentProvider |
| .getVariables(); |
| return libs; |
| } |
| |
| /** |
| * Determines if the present setup is the default location s for this |
| * InterpreterEnvironment |
| * |
| * @return true if the current set of locations are the defaults, false |
| * otherwise |
| */ |
| protected boolean isDefaultLocations() { |
| EnvironmentVariable[] EnvironmentVariables = fEnvironmentVariablesContentProvider |
| .getVariables(); |
| IInterpreterInstall install = getInterpreterInstall(); |
| |
| if (install == null || EnvironmentVariables == null) { |
| return true; |
| } |
| IFileHandle installLocation = install.getInstallLocation(); |
| if (installLocation != null) { |
| EnvironmentVariable[] def = new EnvironmentVariable[0]; |
| if (def.length == EnvironmentVariables.length) { |
| for (int i = 0; i < def.length; i++) { |
| if (!def[i].equals(EnvironmentVariables[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns the Interpreter install associated with this library block or |
| * <code>null</code> if new interpreter is being added. |
| * |
| * @return Interpreter install |
| */ |
| protected IInterpreterInstall getInterpreterInstall() { |
| return fInterpreterInstall; |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| protected IEnvironment getEnvironment() { |
| if (fInterpreterInstall != null) { |
| return fInterpreterInstall.getEnvironment(); |
| } else { |
| return fDialog.getEnvironment(); |
| } |
| } |
| |
| /** |
| * Returns the Interpreter install type associated with this library block. |
| * |
| * @return Interpreter install |
| */ |
| protected IInterpreterInstallType getInterpreterInstallType() { |
| return fInterpreterInstallType; |
| } |
| |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| Object source = e.getSource(); |
| /* |
| * if (source == fUpButton) { fEnvironmentVariablesContentProvider |
| * .up(fLibraryViewer.getStructuredSelection()); } else if (source == |
| * fDownButton) { fEnvironmentVariablesContentProvider |
| * .down(fLibraryViewer.getStructuredSelection()); } else |
| */ |
| if (source == fRemoveButton) { |
| EnvironmentVariable[] old = this.fEnvironmentVariablesContentProvider |
| .getVariables(); |
| fEnvironmentVariablesContentProvider |
| .remove(fVariablesViewer.getStructuredSelection()); |
| fDialog.updateLibraries( |
| this.fEnvironmentVariablesContentProvider.getVariables(), |
| old); |
| fDialog.updateValidateInterpreterLocation(); |
| } else if (source == fAddExistedButton) { |
| addExisted(fVariablesViewer.getStructuredSelection()); |
| } else if (source == fAddButton) { |
| handleAdd(); |
| } else if (source == fEditButton) { |
| EnvironmentVariable[] old = this.fEnvironmentVariablesContentProvider |
| .getVariables(); |
| if (edit(fVariablesViewer.getStructuredSelection())) { |
| fDialog.updateLibraries( |
| this.fEnvironmentVariablesContentProvider |
| .getVariables(), |
| old); |
| fDialog.updateValidateInterpreterLocation(); |
| } |
| } else if (source == fImportButton) { |
| if (performImport()) { |
| fDialog.updateValidateInterpreterLocation(); |
| } |
| } else if (source == fExportButton) { |
| performExport(); |
| } |
| update(); |
| } |
| |
| private void performExport() { |
| FileDialog dialog = new FileDialog(this.fDialog.getShell(), SWT.SAVE); |
| dialog.setOverwrite(true); |
| dialog.setText( |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_exportEnvironmentVariablesToFile); |
| String file = dialog.open(); |
| if (file != null) { |
| EnvironmentVariable[] variables = this.fEnvironmentVariablesContentProvider |
| .getVariables(); |
| try { |
| EnvironmentVariablesFileUtils.save(variables, file); |
| } catch (Exception e) { |
| // String text = "Failed to save environment variables"; |
| showErrorMessage( |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_environmentExport, |
| e.getMessage()); |
| } |
| } |
| } |
| |
| private void showErrorMessage(String title, String text) { |
| MessageBox box = new MessageBox(this.fDialog.getShell(), |
| SWT.ERROR_UNSPECIFIED); |
| box.setText(title); |
| box.setMessage(text); |
| box.open(); |
| } |
| |
| private boolean performImport() { |
| FileDialog dialog = new FileDialog(this.fDialog.getShell(), SWT.OPEN); |
| dialog.setText( |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_importEnvironmentVariablesFromFile); |
| String file = dialog.open(); |
| if (file != null) { |
| File handle = new File(file); |
| if (!handle.exists()) { |
| String text = InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_selectedFileDoesntExist; |
| showErrorMessage( |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_environmentImport, |
| text); |
| return false; |
| } |
| EnvironmentVariable[] vars = null; |
| try { |
| vars = EnvironmentVariablesFileUtils.load(file); |
| } catch (Exception e) { |
| showErrorMessage( |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_environmentImport, |
| e.getMessage()); |
| return false; |
| } |
| if (vars != null) { |
| EnvironmentVariable[] variables = this.fEnvironmentVariablesContentProvider |
| .getVariables(); |
| Set<EnvironmentVariable> nvars = new HashSet<>(); |
| nvars.addAll(Arrays.asList(vars)); |
| nvars.addAll(Arrays.asList(variables)); |
| this.fEnvironmentVariablesContentProvider.setVariables( |
| nvars.toArray(new EnvironmentVariable[nvars.size()])); |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| private boolean edit(IStructuredSelection selection) { |
| EnvironmentVariable var = (EnvironmentVariable) selection |
| .getFirstElement(); |
| if (var == null) { |
| return false; |
| } |
| String originalName = var.getName(); |
| String value = var.getValue(); |
| MultipleInputDialog dialog = new MultipleInputDialog(fDialog.getShell(), |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_editVariable); |
| dialog.addTextField(NAME_LABEL, originalName, false); |
| dialog.addVariablesField(VALUE_LABEL, value, true); |
| |
| if (dialog.open() != Window.OK) { |
| return false; |
| } |
| String name = dialog.getStringValue(NAME_LABEL); |
| value = dialog.getStringValue(VALUE_LABEL); |
| if (!originalName.equals(name)) { |
| final EnvironmentVariable newVar = new EnvironmentVariable(name, |
| value); |
| if (fEnvironmentVariablesContentProvider.addVariable(newVar)) { |
| fEnvironmentVariablesContentProvider |
| .remove(new StructuredSelection(var)); |
| fVariablesViewer.setSelection(new StructuredSelection(newVar), |
| true); |
| } |
| } else { |
| var.setValue(value); |
| fVariablesViewer.refresh(true); |
| } |
| return true; |
| } |
| |
| @Override |
| public void widgetDefaultSelected(SelectionEvent e) { |
| } |
| |
| private void handleAdd() { |
| EnvironmentVariable newVar = add(); |
| if (newVar == null) |
| return; |
| EnvironmentVariable[] old = this.fEnvironmentVariablesContentProvider |
| .getVariables(); |
| fEnvironmentVariablesContentProvider.addVariable(newVar); |
| fVariablesViewer.setSelection(new StructuredSelection(newVar), true); |
| fVariablesViewer.refresh(); |
| fDialog.updateLibraries( |
| this.fEnvironmentVariablesContentProvider.getVariables(), old); |
| update(); |
| fDialog.updateValidateInterpreterLocation(); |
| } |
| |
| private EnvironmentVariable add() { |
| MultipleInputDialog dialog = new MultipleInputDialog(fDialog.getShell(), |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_addVariable); |
| dialog.addTextField(NAME_LABEL, null, false); |
| dialog.addVariablesField(VALUE_LABEL, null, true); |
| |
| if (dialog.open() != Window.OK) { |
| return null; |
| } |
| |
| String name = dialog.getStringValue(NAME_LABEL); |
| String value = dialog.getStringValue(VALUE_LABEL); |
| |
| if (name != null && value != null && name.length() > 0 |
| && value.length() > 0) { |
| return new EnvironmentVariable(name.trim(), value.trim()); |
| } |
| return null; |
| } |
| |
| private void addExisted(IStructuredSelection selection) { |
| EnvironmentVariable[] libs = addExisted(); |
| if (libs == null) |
| return; |
| EnvironmentVariable[] old = this.fEnvironmentVariablesContentProvider |
| .getVariables(); |
| fEnvironmentVariablesContentProvider.add(libs, selection); |
| fDialog.updateLibraries( |
| this.fEnvironmentVariablesContentProvider.getVariables(), old); |
| update(); |
| fDialog.updateValidateInterpreterLocation(); |
| } |
| |
| @Override |
| public void selectionChanged(SelectionChangedEvent event) { |
| updateButtons(); |
| } |
| |
| /** |
| * Refresh the enable/disable state for the buttons. |
| */ |
| private void updateButtons() { |
| IStructuredSelection selection = fVariablesViewer |
| .getStructuredSelection(); |
| fRemoveButton.setEnabled(!selection.isEmpty()); |
| fEditButton.setEnabled(selection.size() == 1); |
| @SuppressWarnings("unused") |
| boolean enableUp = true, enableDown = true; |
| Object[] libraries = fEnvironmentVariablesContentProvider |
| .getElements(null); |
| if (selection.isEmpty() || libraries.length == 0) { |
| enableUp = false; |
| enableDown = false; |
| } else { |
| Object first = libraries[0]; |
| Object last = libraries[libraries.length - 1]; |
| for (Iterator<?> iter = selection.iterator(); iter.hasNext();) { |
| Object element = iter.next(); |
| Object lib; |
| lib = element; |
| if (lib == first) { |
| enableUp = false; |
| } |
| if (lib == last) { |
| enableDown = false; |
| } |
| } |
| } |
| // fUpButton.setEnabled(enableUp); |
| // fDownButton.setEnabled(enableDown); |
| } |
| |
| /** |
| * Initializes this control based on the settings in the given Interpreter |
| * install and type. |
| * |
| * @param interpreter |
| * Interpreter or <code>null</code> if none |
| * @param type |
| * type of Interpreter install |
| */ |
| public void initializeFrom(IInterpreterInstall interpreter, |
| IInterpreterInstallType type) { |
| fInterpreterInstall = interpreter; |
| fInterpreterInstallType = type; |
| if (interpreter != null) { |
| fEnvironmentVariablesContentProvider.setVariables( |
| getInterpreterInstall().getEnvironmentVariables()); |
| } |
| update(); |
| } |
| |
| protected IBaseLabelProvider getLabelProvider() { |
| return new EnvironmentVariablesLabelProvider(); |
| } |
| |
| protected void updateDialogStatus(IStatus status) { |
| fDialog.setSystemLibraryStatus(status); |
| fDialog.updateStatusLine(); |
| } |
| |
| protected void setButtonLayoutData(Button button) { |
| fDialog.setButtonLayoutData(button); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| @Deprecated |
| protected final void getDialogSettions() { |
| |
| } |
| |
| protected EnvironmentVariable[] addExisted() { |
| |
| // get Environment Variables from the Environment |
| Map<String, EnvironmentVariable> envVariables = getNativeEnvironment(); |
| if (envVariables.size() == 0) { |
| MessageBox box = new MessageBox(fDialog.getShell(), SWT.ICON_ERROR); |
| box.setMessage(NLS.bind( |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_couldNotRetrieveEnvironmentVariablesFrom, |
| fDialog.getEnvironment().getName())); |
| box.setText( |
| InterpretersMessages.AbstractInterpreterEnvironmentVariablesBlock_failedToRetrieveEnvironment); |
| box.open(); |
| return null; |
| } |
| |
| // get Environment Variables from the table |
| for (EnvironmentVariable var : fEnvironmentVariablesContentProvider |
| .getVariables()) { |
| envVariables.remove(var.getName()); |
| } |
| |
| ListSelectionDialog dialog = new ListSelectionDialog(fDialog.getShell(), |
| envVariables, createSelectionDialogContentProvider(), |
| createSelectionDialogLabelProvider(), |
| LaunchConfigurationsMessages.EnvironmentTab_19); |
| dialog.setTitle(LaunchConfigurationsMessages.EnvironmentTab_20); |
| |
| int button = dialog.open(); |
| if (button == Window.OK) { |
| Object[] selected = dialog.getResult(); |
| EnvironmentVariable[] vars = new EnvironmentVariable[selected.length]; |
| for (int i = 0; i < vars.length; i++) { |
| vars[i] = (EnvironmentVariable) selected[i]; |
| } |
| return vars; |
| } |
| return null; |
| } |
| |
| private ILabelProvider createSelectionDialogLabelProvider() { |
| return new LabelProvider() { |
| @Override |
| public Image getImage(Object element) { |
| return DebugPluginImages |
| .getImage(IDebugUIConstants.IMG_OBJS_ENVIRONMENT); |
| } |
| |
| @Override |
| public String getText(Object element) { |
| EnvironmentVariable var = (EnvironmentVariable) element; |
| return NLS.bind(LaunchConfigurationsMessages.EnvironmentTab_7, |
| var.getName(), var.getValue()); |
| } |
| }; |
| } |
| |
| private IStructuredContentProvider createSelectionDialogContentProvider() { |
| return new IStructuredContentProvider() { |
| @Override |
| public Object[] getElements(Object inputElement) { |
| if (inputElement instanceof Map<?, ?>) { |
| @SuppressWarnings("unchecked") |
| final Map<String, EnvironmentVariable> env = (Map<String, EnvironmentVariable>) inputElement; |
| final EnvironmentVariable[] elements = env.values() |
| .toArray(new EnvironmentVariable[env.size()]); |
| Arrays.sort(elements, |
| (s1, s2) -> s1.getName().compareTo(s2.getName())); |
| return elements; |
| } else { |
| return new EnvironmentVariable[0]; |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| } |
| |
| @Override |
| public void inputChanged(Viewer viewer, Object oldInput, |
| Object newInput) { |
| } |
| }; |
| } |
| |
| private Map<String, EnvironmentVariable> getNativeEnvironment() { |
| IEnvironment environment = fDialog.getEnvironment(); |
| IExecutionEnvironment execEnvironment = environment |
| .getAdapter(IExecutionEnvironment.class); |
| Map<String, String> stringVars = execEnvironment |
| .getEnvironmentVariables(true); |
| HashMap<String, EnvironmentVariable> vars = new HashMap<>(); |
| if (stringVars != null) { |
| for (Map.Entry<String, String> entry : stringVars.entrySet()) { |
| vars.put(entry.getKey(), new EnvironmentVariable(entry.getKey(), |
| entry.getValue())); |
| } |
| } |
| return vars; |
| } |
| } |