| /******************************************************************************* |
| * 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.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.dltk.core.environment.EnvironmentManager; |
| import org.eclipse.dltk.core.environment.IEnvironment; |
| import org.eclipse.dltk.core.environment.IFileHandle; |
| import org.eclipse.dltk.debug.ui.DLTKDebugUIPlugin; |
| import org.eclipse.dltk.internal.ui.util.SWTUtil; |
| import org.eclipse.dltk.internal.ui.util.TableLayoutComposite; |
| import org.eclipse.dltk.launching.IInterpreterInstall; |
| import org.eclipse.dltk.launching.IInterpreterInstallType; |
| import org.eclipse.dltk.launching.InterpreterSearcher; |
| import org.eclipse.dltk.launching.InterpreterStandin; |
| import org.eclipse.dltk.launching.ScriptRuntime; |
| import org.eclipse.dltk.ui.util.PixelConverter; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.viewers.CheckboxTableViewer; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerComparator; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| 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.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Combo; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| |
| /** |
| * A composite that displays installed InterpreterEnvironment's in a table. |
| * InterpreterEnvironments can be added, removed, edited, and searched for. |
| * <p> |
| * This block implements ISelectionProvider - it sends selection change events |
| * when the checked InterpreterEnvironment in the table changes, or when the |
| * "use default" button check state changes. |
| * </p> |
| * @ |
| */ |
| public abstract class InterpretersBlock |
| implements IAddInterpreterDialogRequestor, ISelectionProvider { |
| |
| /** |
| * This block's control |
| */ |
| private Composite fControl; |
| |
| /** |
| * Interpreters being displayed |
| */ |
| protected List<IInterpreterInstall> fInterpreters = new ArrayList<>(); |
| |
| /** |
| * The main list control |
| */ |
| protected CheckboxTableViewer fInterpreterList; |
| |
| // Action buttons |
| private Button fAddButton; |
| private Button fRemoveButton; |
| private Button fEditButton; |
| private Button fCopyButton; |
| private Button fSearchButton; |
| |
| private Combo fEnvironments; |
| |
| /** |
| * Environment to checked interpreter. |
| */ |
| private Map<IEnvironment, IInterpreterInstall> checkedInterpreters = new HashMap<>(); |
| |
| // index of column used for sorting |
| private int fSortColumn = 0; |
| |
| /** |
| * Selection listeners (checked InterpreterEnvironment changes) |
| */ |
| private ListenerList<ISelectionChangedListener> fSelectionListeners = new ListenerList<>(); |
| |
| /** |
| * Previous selection |
| */ |
| private ISelection fPrevSelection = new StructuredSelection(); |
| |
| private Table fTable; |
| |
| /** |
| * Content provider to show a list of InterpreterEnvironments |
| */ |
| class InterpretersContentProvider implements IStructuredContentProvider { |
| @Override |
| public Object[] getElements(Object input) { |
| return getCurrentInterprers(); |
| } |
| |
| @Override |
| public void inputChanged(Viewer viewer, Object oldInput, |
| Object newInput) { |
| } |
| |
| @Override |
| public void dispose() { |
| } |
| } |
| |
| /** |
| * Label provider for installed InterpreterEnvironments table. |
| */ |
| class InterpreterLabelProvider extends LabelProvider |
| implements ITableLabelProvider { |
| |
| /** |
| * @see ITableLabelProvider#getColumnText(Object, int) |
| */ |
| @Override |
| public String getColumnText(Object element, int columnIndex) { |
| if (element instanceof IInterpreterInstall) { |
| IInterpreterInstall interp = (IInterpreterInstall) element; |
| switch (columnIndex) { |
| case 0: |
| return interp.getName(); |
| case 1: |
| return interp.getInterpreterInstallType().getName(); |
| case 2: |
| return interp.getRawInstallLocation().toOSString(); |
| } |
| } |
| return element.toString(); |
| } |
| |
| /** |
| * @see ITableLabelProvider#getColumnImage(Object, int) |
| */ |
| @Override |
| public Image getColumnImage(Object element, int columnIndex) { |
| if (columnIndex == 0) { |
| // TODO: instert interpreter logo here |
| } |
| return null; |
| } |
| |
| } |
| |
| @Override |
| public void addSelectionChangedListener( |
| ISelectionChangedListener listener) { |
| fSelectionListeners.add(listener); |
| } |
| |
| @Override |
| public ISelection getSelection() { |
| return new StructuredSelection(fInterpreterList.getCheckedElements()); |
| } |
| |
| @Override |
| public void removeSelectionChangedListener( |
| ISelectionChangedListener listener) { |
| fSelectionListeners.remove(listener); |
| } |
| |
| @Override |
| public void setSelection(ISelection selection) { |
| if (selection instanceof IStructuredSelection) { |
| if (!selection.equals(fPrevSelection)) { |
| fPrevSelection = selection; |
| Object interp = ((IStructuredSelection) selection) |
| .getFirstElement(); |
| if (interp == null) { |
| fInterpreterList.setCheckedElements(new Object[0]); |
| } else { |
| fInterpreterList |
| .setCheckedElements(new Object[] { interp }); |
| IInterpreterInstall install = (IInterpreterInstall) interp; |
| checkedInterpreters.put(install.getEnvironment(), install); |
| fInterpreterList.reveal(interp); |
| } |
| fireSelectionChanged(); |
| } |
| } |
| } |
| |
| /** |
| * Creates this block's control in the given control. |
| * |
| * @param ancestor |
| * containing control |
| * @param useManageButton |
| * whether to present a single 'manage...' button |
| * to the user that opens the installed |
| * InterpreterEnvironments pref page for |
| * InterpreterEnvironment management, or to |
| * provide 'add, remove, edit, and search' |
| * buttons. |
| */ |
| public void createControl(Composite ancestor) { |
| |
| Composite parent = new Composite(ancestor, SWT.NULL); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| |
| Font font = ancestor.getFont(); |
| parent.setFont(font); |
| parent.setLayout(layout); |
| |
| fControl = parent; |
| |
| GridData data; |
| |
| Composite env = new Composite(parent, SWT.NONE); |
| GridLayout layout2 = new GridLayout(2, false); |
| layout2.marginLeft = -5; |
| layout2.marginRight = -5; |
| layout2.marginTop = -5; |
| layout2.marginBottom = -5; |
| env.setLayout(layout2); |
| data = new GridData(SWT.FILL, SWT.DEFAULT, true, false); |
| data.horizontalSpan = 2; |
| env.setLayoutData(data); |
| Label environmentLabel = new Label(env, SWT.NONE); |
| environmentLabel.setText(InterpretersMessages.InterpretersBlock_host); |
| this.fEnvironments = new Combo(env, SWT.DROP_DOWN | SWT.READ_ONLY); |
| data = new GridData(SWT.FILL, SWT.DEFAULT, true, false); |
| this.fEnvironments.setLayoutData(data); |
| environments = EnvironmentManager.getEnvironments(); |
| String[] items = new String[environments.length]; |
| int local = 0; |
| for (int i = 0; i < items.length; i++) { |
| items[i] = environments[i].getName(); |
| if (environments[i].isLocal()) { |
| local = i; |
| } |
| } |
| this.fEnvironments.setItems(items); |
| this.fEnvironments.select(local); |
| |
| this.fEnvironments.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| Object install = checkedInterpreters |
| .get(getCurrentEnvironment()); |
| fInterpreterList.refresh(); |
| if (install != null) { |
| fInterpreterList |
| .setCheckedElements(new Object[] { install }); |
| } else { |
| fInterpreterList.setCheckedElements(new Object[0]); |
| } |
| } |
| }); |
| |
| // Label tableLabel = new Label(parent, SWT.NONE); |
| // tableLabel.setText(InterpretersMessages.InstalledInterpretersBlock_15 |
| // ); |
| // data = new GridData(); |
| // data.horizontalSpan = 2; |
| // tableLabel.setLayoutData(data); |
| // tableLabel.setFont(font); |
| |
| PixelConverter conv = new PixelConverter(parent); |
| data = new GridData(GridData.FILL_BOTH); |
| data.widthHint = conv.convertWidthInCharsToPixels(50); |
| TableLayoutComposite tblComposite = new TableLayoutComposite(parent, |
| SWT.NONE); |
| tblComposite.setLayoutData(data); |
| fTable = new Table(tblComposite, |
| SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); |
| |
| data = new GridData(GridData.FILL_BOTH); |
| data.widthHint = 450; |
| fTable.setLayoutData(data); |
| fTable.setFont(font); |
| |
| fTable.setHeaderVisible(true); |
| fTable.setLinesVisible(true); |
| |
| TableColumn column1 = new TableColumn(fTable, SWT.NULL); |
| column1.setText(InterpretersMessages.InstalledInterpretersBlock_0); |
| column1.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| sortByName(); |
| } |
| }); |
| column1.setWidth(conv.convertWidthInCharsToPixels(15)); |
| |
| TableColumn column2 = new TableColumn(fTable, SWT.NULL); |
| column2.setText(InterpretersMessages.InstalledInterpretersBlock_2); |
| column2.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| sortByType(); |
| } |
| }); |
| column2.setWidth(conv.convertWidthInCharsToPixels(15)); |
| |
| TableColumn column3 = new TableColumn(fTable, SWT.NULL); |
| column3.setText(InterpretersMessages.InstalledInterpretersBlock_1); |
| column3.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| sortByLocation(); |
| } |
| }); |
| column3.setWidth(conv.convertWidthInCharsToPixels(20)); |
| |
| fInterpreterList = new CheckboxTableViewer(fTable); |
| fInterpreterList.setLabelProvider(new InterpreterLabelProvider()); |
| fInterpreterList.setContentProvider(new InterpretersContentProvider()); |
| // by default, sort by name |
| sortByName(); |
| |
| fInterpreterList.addSelectionChangedListener(evt -> enableButtons()); |
| |
| fInterpreterList.addCheckStateListener(event -> { |
| if (event.getChecked()) { |
| setCheckedInterpreter((IInterpreterInstall) event.getElement()); |
| } else { |
| setCheckedInterpreter(null); |
| } |
| }); |
| |
| fInterpreterList.addDoubleClickListener(e -> { |
| if (!fInterpreterList.getSelection().isEmpty()) { |
| editInterpreter(); |
| } |
| }); |
| fTable.addKeyListener(new KeyAdapter() { |
| @Override |
| public void keyPressed(KeyEvent event) { |
| if (event.character == SWT.DEL && event.stateMask == 0) { |
| if (fRemoveButton.getEnabled()) |
| removeInterpreters(); |
| } |
| } |
| }); |
| |
| fTable.layout(); |
| |
| buttons = new Composite(parent, SWT.NULL); |
| buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); |
| layout = new GridLayout(); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| buttons.setLayout(layout); |
| buttons.setFont(font); |
| |
| fAddButton = createPushButton(buttons, |
| InterpretersMessages.InstalledInterpretersBlock_3); |
| fAddButton.addListener(SWT.Selection, evt -> addInterpreter()); |
| |
| fEditButton = createPushButton(buttons, |
| InterpretersMessages.InstalledInterpretersBlock_4); |
| fEditButton.addListener(SWT.Selection, evt -> editInterpreter()); |
| |
| fCopyButton = createPushButton(buttons, |
| InterpretersMessages.InstalledInterpretersBlock_16); |
| fCopyButton.addListener(SWT.Selection, evt -> copyInterpreter()); |
| |
| fRemoveButton = createPushButton(buttons, |
| InterpretersMessages.InstalledInterpretersBlock_5); |
| fRemoveButton.addListener(SWT.Selection, evt -> removeInterpreters()); |
| |
| // copied from ListDialogField.CreateSeparator() |
| Label separator = new Label(buttons, SWT.NONE); |
| separator.setVisible(false); |
| GridData gd = new GridData(); |
| gd.horizontalAlignment = GridData.FILL; |
| gd.verticalAlignment = GridData.BEGINNING; |
| gd.heightHint = 4; |
| separator.setLayoutData(gd); |
| |
| fSearchButton = createPushButton(buttons, |
| InterpretersMessages.InstalledInterpretersBlock_6); |
| fSearchButton.addListener(SWT.Selection, evt -> search()); |
| |
| fillWithWorkspaceInterpreters(); |
| enableButtons(); |
| fAddButton.setEnabled(ScriptRuntime |
| .getInterpreterInstallTypes(getCurrentNature()).length > 0); |
| } |
| |
| /** |
| * Fire current selection |
| */ |
| private void fireSelectionChanged() { |
| SelectionChangedEvent event = new SelectionChangedEvent(this, |
| getSelection()); |
| for (ISelectionChangedListener listener : fSelectionListeners) { |
| listener.selectionChanged(event); |
| } |
| } |
| |
| /** |
| * Sorts by Interpreter type, and name within type. |
| */ |
| private void sortByType() { |
| fInterpreterList.setComparator(new ViewerComparator() { |
| @Override |
| public int compare(Viewer viewer, Object e1, Object e2) { |
| if ((e1 instanceof IInterpreterInstall) |
| && (e2 instanceof IInterpreterInstall)) { |
| IInterpreterInstall left = (IInterpreterInstall) e1; |
| IInterpreterInstall right = (IInterpreterInstall) e2; |
| String leftType = left.getInterpreterInstallType() |
| .getName(); |
| String rightType = right.getInterpreterInstallType() |
| .getName(); |
| int res = leftType.compareToIgnoreCase(rightType); |
| if (res != 0) { |
| return res; |
| } |
| return left.getName().compareToIgnoreCase(right.getName()); |
| } |
| return super.compare(viewer, e1, e2); |
| } |
| |
| @Override |
| public boolean isSorterProperty(Object element, String property) { |
| return true; |
| } |
| }); |
| fSortColumn = 3; |
| } |
| |
| /** |
| * Sorts by Interpreter name. |
| */ |
| private void sortByName() { |
| fInterpreterList.setComparator(new ViewerComparator() { |
| @Override |
| public int compare(Viewer viewer, Object e1, Object e2) { |
| if ((e1 instanceof IInterpreterInstall) |
| && (e2 instanceof IInterpreterInstall)) { |
| IInterpreterInstall left = (IInterpreterInstall) e1; |
| IInterpreterInstall right = (IInterpreterInstall) e2; |
| return left.getName().compareToIgnoreCase(right.getName()); |
| } |
| return super.compare(viewer, e1, e2); |
| } |
| |
| @Override |
| public boolean isSorterProperty(Object element, String property) { |
| return true; |
| } |
| }); |
| fSortColumn = 1; |
| } |
| |
| /** |
| * Sorts by Interpreter location. |
| */ |
| private void sortByLocation() { |
| fInterpreterList.setComparator(new ViewerComparator() { |
| @Override |
| public int compare(Viewer viewer, Object e1, Object e2) { |
| if ((e1 instanceof IInterpreterInstall) |
| && (e2 instanceof IInterpreterInstall)) { |
| IInterpreterInstall left = (IInterpreterInstall) e1; |
| IInterpreterInstall right = (IInterpreterInstall) e2; |
| return left.getInstallLocation().toString() |
| .compareToIgnoreCase( |
| right.getInstallLocation().toString()); |
| } |
| return super.compare(viewer, e1, e2); |
| } |
| |
| @Override |
| public boolean isSorterProperty(Object element, String property) { |
| return true; |
| } |
| }); |
| fSortColumn = 2; |
| } |
| |
| protected void enableButtons() { |
| IStructuredSelection selection = fInterpreterList |
| .getStructuredSelection(); |
| int selectionCount = selection.size(); |
| fEditButton.setEnabled(selectionCount == 1); |
| fCopyButton.setEnabled(selectionCount > 0); |
| if (selectionCount > 0) { |
| Iterator<?> iterator = selection.iterator(); |
| while (iterator.hasNext()) { |
| IInterpreterInstall install = (IInterpreterInstall) iterator |
| .next(); |
| if (isContributed(install)) { |
| fRemoveButton.setEnabled(false); |
| return; |
| } |
| } |
| fRemoveButton.setEnabled(true); |
| } else { |
| fRemoveButton.setEnabled(false); |
| } |
| } |
| |
| protected Button createPushButton(Composite parent, String label) { |
| return SWTUtil.createPushButton(parent, label, null); |
| } |
| |
| private boolean isContributed(IInterpreterInstall install) { |
| return ScriptRuntime.isContributedInterpreterInstall(install.getId()); |
| } |
| |
| /** |
| * Returns this block's control |
| * |
| * @return control |
| */ |
| public Control getControl() { |
| return fControl; |
| } |
| |
| /** |
| * Sets the InterpreterEnvironments to be displayed in this block |
| * |
| * @param Interpreters |
| * InterpreterEnvironments to be displayed |
| */ |
| protected void setInterpreters(IInterpreterInstall[] Interpreters) { |
| fInterpreters.clear(); |
| for (int i = 0; i < Interpreters.length; i++) { |
| fInterpreters.add(Interpreters[i]); |
| } |
| fInterpreterList.setInput(fInterpreters); |
| fInterpreterList.refresh(); |
| } |
| |
| /** |
| * Returns the InterpreterEnvironments currently being displayed in this |
| * block |
| * |
| * @return InterpreterEnvironments currently being displayed in this block |
| */ |
| public IInterpreterInstall[] getInterpreters() { |
| return fInterpreters |
| .toArray(new IInterpreterInstall[fInterpreters.size()]); |
| } |
| |
| public IInterpreterInstall[] getCurrentInterprers() { |
| IEnvironment environment = getCurrentEnvironment(); |
| List<IInterpreterInstall> result = new ArrayList<>(); |
| for (Iterator<IInterpreterInstall> iterator = fInterpreters |
| .iterator(); iterator.hasNext();) { |
| IInterpreterInstall install = iterator.next(); |
| if (install.getInstallLocation().getEnvironmentId() |
| .equals(environment.getId())) { |
| result.add(install); |
| } |
| } |
| return result.toArray(new IInterpreterInstall[result.size()]); |
| } |
| |
| /** |
| * @see IAddInterpreterDialogRequestor#isDuplicateName(String) |
| */ |
| @Override |
| public boolean isDuplicateName(String name, |
| IInterpreterInstall editedInterpreter) { |
| for (int i = 0; i < fInterpreters.size(); i++) { |
| IInterpreterInstall interpreter = fInterpreters.get(i); |
| if (interpreter.getName().equals(name)) { |
| if (interpreter != editedInterpreter) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * @see IAddInterpreterDialogRequestor#isDuplicateName(String) |
| */ |
| public boolean isDuplicate(IFileHandle location) { |
| for (int i = 0; i < fInterpreters.size(); i++) { |
| IInterpreterInstall interpreter = fInterpreters.get(i); |
| if (interpreter.getInstallLocation().equals(location)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private void removeInterpreters() { |
| IStructuredSelection selection = fInterpreterList |
| .getStructuredSelection(); |
| IInterpreterInstall[] Interpreters = new IInterpreterInstall[selection |
| .size()]; |
| Iterator<?> iter = selection.iterator(); |
| int i = 0; |
| while (iter.hasNext()) { |
| Interpreters[i] = (IInterpreterInstall) iter.next(); |
| i++; |
| } |
| removeInterpreters(Interpreters); |
| } |
| |
| /** |
| * Removes the given Interpreters from the table. |
| * |
| * @param Interpreters |
| */ |
| public void removeInterpreters(IInterpreterInstall[] Interpreters) { |
| IStructuredSelection prev = (IStructuredSelection) getSelection(); |
| for (int i = 0; i < Interpreters.length; i++) { |
| fInterpreters.remove(Interpreters[i]); |
| } |
| fInterpreterList.refresh(); |
| IStructuredSelection curr = (IStructuredSelection) getSelection(); |
| if (!curr.equals(prev)) { |
| IInterpreterInstall[] installs = getInterpreters(); |
| if (curr.size() == 0 && installs.length == 1) { |
| // pick a default Interpreter automatically |
| setSelection(new StructuredSelection(installs[0])); |
| } else { |
| fireSelectionChanged(); |
| } |
| } |
| } |
| |
| /** |
| * Search for installed interpreters in the file system |
| */ |
| protected void search() { |
| |
| // choose a root directory for the search |
| // ignore installed locations |
| final Set<IFileHandle> exstingLocations = new HashSet<>(); |
| Iterator<IInterpreterInstall> iter = fInterpreters.iterator(); |
| while (iter.hasNext()) { |
| exstingLocations.add(iter.next().getInstallLocation()); |
| } |
| |
| // search |
| final InterpreterSearcher searcher = new InterpreterSearcher(); |
| |
| final IEnvironment currentEnvironment = getCurrentEnvironment(); |
| |
| IRunnableWithProgress r = monitor -> { |
| try { |
| monitor.beginTask( |
| InterpretersMessages.InstalledInterpretersBlock_11, |
| IProgressMonitor.UNKNOWN); |
| |
| searcher.search(currentEnvironment, getCurrentNature(), |
| exstingLocations, 1, monitor); |
| } finally { |
| monitor.done(); |
| } |
| }; |
| |
| try { |
| ProgressMonitorDialog progress = new ProgressMonitorDialog( |
| getShell()) { |
| |
| @Override |
| protected void createCancelButton(Composite parent) { |
| super.createCancelButton(parent); |
| cancel.setText(InterpretersMessages.InterpretersBlock_0); |
| } |
| |
| }; |
| progress.run(true, true, r); |
| } catch (InvocationTargetException e) { |
| DLTKDebugUIPlugin.log(e); |
| } catch (InterruptedException e) { |
| return; // cancelled |
| } |
| final int[] widths = { 15, 15 }; |
| if (!searcher.hasResults()) { |
| MessageDialog.openInformation(getShell(), |
| InterpretersMessages.InstalledInterpretersBlock_12, |
| InterpretersMessages.InstalledInterpretersBlock_113); |
| } else { |
| final IFileHandle[] locations = searcher.getFoundFiles(); |
| final IInterpreterInstallType[] types = searcher |
| .getFoundInstallTypes(); |
| boolean added = false; |
| for (int i = 0; i < locations.length; ++i) { |
| final IFileHandle file = locations[i]; |
| final IInterpreterInstallType type = types[i]; |
| if (isDuplicate(file)) { |
| continue; |
| } |
| added = true; |
| |
| IInterpreterInstall interpreter = new InterpreterStandin(type, |
| createUniqueId(type)); |
| final String name = file.getName(); |
| |
| String nameCopy = name; |
| int j = 1; |
| while (isDuplicateName(nameCopy, null)) { |
| nameCopy = name + '(' + (j++) + ')'; |
| } |
| if (widths[0] < nameCopy.length()) { |
| widths[0] = nameCopy.length() + 2; |
| } |
| if (widths[1] < type.getName().length()) { |
| widths[1] = type.getName().length() + 2; |
| } |
| interpreter.setName(nameCopy); |
| interpreter.setInstallLocation(file); |
| interpreterAdded(interpreter); |
| } |
| if (!added) { |
| MessageDialog.openInformation(getShell(), |
| InterpretersMessages.InstalledInterpretersBlock_12, |
| InterpretersMessages.InstalledInterpretersBlock_113); |
| } |
| fTable.getDisplay().asyncExec(() -> { |
| PixelConverter conv = new PixelConverter(fTable); |
| for (int i = 0; i < 2; i++) { |
| int nw1 = conv.convertWidthInCharsToPixels(widths[i]); |
| TableColumn cl0 = fTable.getColumn(i); |
| if (cl0.getWidth() < nw1) { |
| cl0.setWidth(nw1); |
| } |
| } |
| fTable.layout(); |
| }); |
| } |
| } |
| |
| protected Shell getShell() { |
| return getControl().getShell(); |
| } |
| |
| /** |
| * Sets the checked InterpreterEnvironment, possible <code>null</code> |
| * |
| * @param interpreter |
| * InterpreterEnvironment or <code>null</code> |
| */ |
| public void setCheckedInterpreter(IInterpreterInstall interpreter) { |
| if (interpreter == null) { |
| setSelection(new StructuredSelection()); |
| } else { |
| if (interpreter.getEnvironment().equals(getCurrentEnvironment())) { |
| setSelection(new StructuredSelection(interpreter)); |
| } |
| checkedInterpreters.put(interpreter.getEnvironment(), interpreter); |
| } |
| } |
| |
| /** |
| * Returns the checked Interpreter or <code>null</code> if none. |
| * |
| * @return the checked Interpreter or <code>null</code> if none |
| */ |
| public IInterpreterInstall[] getCheckedInterpreters() { |
| Collection<IInterpreterInstall> values = checkedInterpreters.values(); |
| IInterpreterInstall[] installs = new IInterpreterInstall[values.size()]; |
| int i = 0; |
| for (Iterator<IInterpreterInstall> iterator = values |
| .iterator(); iterator.hasNext();) { |
| installs[i] = iterator.next(); |
| ++i; |
| } |
| return installs; |
| } |
| |
| /** |
| * Persist table settings into the give dialog store, prefixed with the |
| * given key. |
| * |
| * @param settings |
| * dialog store |
| * @param qualifier |
| * key qualifier |
| */ |
| public void saveColumnSettings(IDialogSettings settings, String qualifier) { |
| int columnCount = fTable.getColumnCount(); |
| for (int i = 0; i < columnCount; i++) { |
| settings.put(qualifier + ".columnWidth" + i, //$NON-NLS-1$ |
| fTable.getColumn(i).getWidth()); |
| } |
| settings.put(qualifier + ".sortColumn", fSortColumn); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Restore table settings from the given dialog store using the given key. |
| * |
| * @param settings |
| * dialog settings store |
| * @param qualifier |
| * key to restore settings from |
| */ |
| public void restoreColumnSettings(IDialogSettings settings, |
| String qualifier) { |
| fInterpreterList.getTable().layout(true); |
| restoreColumnWidths(settings, qualifier); |
| try { |
| fSortColumn = settings.getInt(qualifier + ".sortColumn"); //$NON-NLS-1$ |
| } catch (NumberFormatException e) { |
| fSortColumn = 1; |
| } |
| switch (fSortColumn) { |
| case 1: |
| sortByName(); |
| break; |
| case 2: |
| sortByLocation(); |
| break; |
| case 3: |
| sortByType(); |
| break; |
| } |
| } |
| |
| private void restoreColumnWidths(IDialogSettings settings, |
| String qualifier) { |
| int columnCount = fTable.getColumnCount(); |
| for (int i = 0; i < columnCount; i++) { |
| int width = -1; |
| |
| try { |
| width = settings.getInt(qualifier + ".columnWidth" + i); //$NON-NLS-1$ |
| } catch (NumberFormatException e) { |
| } |
| |
| if (width <= 0) { |
| fTable.getColumn(i).pack(); |
| } else { |
| fTable.getColumn(i).setWidth(width); |
| } |
| } |
| } |
| |
| /** |
| * Populates the InterpreterEnvironment table with existing |
| * InterpreterEnvironments defined in the workspace. |
| */ |
| protected void fillWithWorkspaceInterpreters() { |
| // fill with interpreters |
| List<InterpreterStandin> standins = new ArrayList<>(); |
| IInterpreterInstallType[] types = ScriptRuntime |
| .getInterpreterInstallTypes(getCurrentNature()); |
| for (int i = 0; i < types.length; i++) { |
| IInterpreterInstallType type = types[i]; |
| IInterpreterInstall[] installs = type.getInterpreterInstalls(); |
| if (installs != null) |
| for (int j = 0; j < installs.length; j++) { |
| IInterpreterInstall install = installs[j]; |
| standins.add(new InterpreterStandin(install)); |
| } |
| } |
| setInterpreters( |
| standins.toArray(new IInterpreterInstall[standins.size()])); |
| } |
| |
| @Override |
| public void interpreterAdded(IInterpreterInstall Interpreter) { |
| fInterpreters.add(Interpreter); |
| fInterpreterList.refresh(); |
| |
| IInterpreterInstall[] installs = getCurrentInterprers(); |
| if (installs.length == 1) { |
| // pick a default Interpreter automatically |
| setSelection(new StructuredSelection(installs[0])); |
| } |
| fireSelectionChanged(); |
| packColumns(); |
| } |
| |
| protected void packColumns() { |
| final int columnCount = fTable.getColumnCount(); |
| for (int i = 0; i < columnCount; ++i) { |
| fTable.getColumn(i).pack(); |
| } |
| } |
| |
| // Make sure that InterpreterStandin ids are unique if multiple calls to |
| // System.currentTimeMillis() |
| // happen very quickly |
| private static String fgLastUsedID; |
| |
| private IEnvironment[] environments; |
| |
| protected Composite buttons; |
| |
| /** |
| * Find a unique Interpreter id. Check existing 'real' Interpreters, as well |
| * as the last id used for a InterpreterStandin. |
| */ |
| protected String createUniqueId(IInterpreterInstallType InterpreterType) { |
| String id = null; |
| do { |
| id = String.valueOf(System.currentTimeMillis()); |
| } while (InterpreterType.findInterpreterInstall(id) != null |
| || id.equals(fgLastUsedID)); |
| fgLastUsedID = id; |
| return id; |
| } |
| |
| /** |
| * Compares the given name against current names and adds the appropriate |
| * numerical suffix to ensure that it is unique. |
| * |
| * @param name |
| * the name with which to ensure uniqueness |
| * @return the unique version of the given name |
| * |
| */ |
| protected String generateName(String name) { |
| if (!isDuplicateName(name, null)) { |
| return name; |
| } |
| |
| if (name.matches(".*\\(\\d*\\)")) { //$NON-NLS-1$ |
| int start = name.lastIndexOf('('); |
| int end = name.lastIndexOf(')'); |
| String stringInt = name.substring(start + 1, end); |
| int numericValue = Integer.parseInt(stringInt); |
| String newName = name.substring(0, start + 1) + (numericValue + 1) |
| + ")"; //$NON-NLS-1$ |
| return generateName(newName); |
| } else { |
| return generateName(name + " (1)"); //$NON-NLS-1$ |
| } |
| } |
| |
| abstract protected String getCurrentNature(); |
| |
| /** |
| * Creates the {@link IInterpreterInstall} add/edit dialog. Should be |
| * overridden. |
| * |
| * @param environment |
| * @param standin |
| * @return @ |
| */ |
| protected IScriptInterpreterDialog createInterpreterDialog( |
| IEnvironment environment, IInterpreterInstall standin) { |
| // backwards compatible implementation |
| final AddScriptInterpreterDialog dialog = createInterpreterDialog( |
| standin); |
| if (dialog != null) { |
| dialog.setEnvironment(environment); |
| } |
| return dialog; |
| } |
| |
| /** |
| * @param standin |
| * @return |
| * @deprecated createInterpreterDialog(IEnvironment,IInterpreterInstall) |
| * method above should be overridden. This one is kept for |
| * compatibility purposes only. |
| */ |
| @Deprecated |
| protected AddScriptInterpreterDialog createInterpreterDialog( |
| IInterpreterInstall standin) { |
| return null; |
| } |
| |
| protected void copyInterpreter() { |
| IStructuredSelection selection = fInterpreterList |
| .getStructuredSelection(); |
| Iterator<?> it = selection.iterator(); |
| |
| ArrayList<InterpreterStandin> newEntries = new ArrayList<>(); |
| while (it.hasNext()) { |
| IInterpreterInstall selectedInterpreter = (IInterpreterInstall) it |
| .next(); |
| |
| // duplicate & add Interpreter |
| InterpreterStandin standin = new InterpreterStandin( |
| selectedInterpreter, createUniqueId( |
| selectedInterpreter.getInterpreterInstallType())); |
| standin.setName(generateName(selectedInterpreter.getName())); |
| IScriptInterpreterDialog dialog = createInterpreterDialog( |
| getCurrentEnvironment(), standin); |
| if (dialog == null) |
| return; |
| dialog.setTitle(InterpretersMessages.InstalledInterpretersBlock_18); |
| if (!dialog.execute()) { |
| return; |
| } |
| newEntries.add(standin); |
| fInterpreters.add(standin); |
| } |
| fInterpreterList.refresh(); |
| fInterpreterList |
| .setSelection(new StructuredSelection(newEntries.toArray())); |
| } |
| |
| /** |
| * Bring up a dialog that lets the user create a new Interpreter definition. |
| */ |
| protected void addInterpreter() { |
| IScriptInterpreterDialog dialog = createInterpreterDialog( |
| getCurrentEnvironment(), null); |
| if (dialog == null) |
| return; |
| dialog.setTitle(InterpretersMessages.InstalledInterpretersBlock_7); |
| if (!dialog.execute()) { |
| return; |
| } |
| fInterpreterList.refresh(); |
| } |
| |
| protected void editInterpreter() { |
| IStructuredSelection selection = (IStructuredSelection) fInterpreterList |
| .getSelection(); |
| IInterpreterInstall install = (IInterpreterInstall) selection |
| .getFirstElement(); |
| |
| if (install == null) { |
| return; |
| } |
| |
| IScriptInterpreterDialog dialog = createInterpreterDialog( |
| getCurrentEnvironment(), install); |
| if (dialog == null) |
| return; |
| dialog.setTitle(InterpretersMessages.InstalledInterpretersBlock_8); |
| if (!dialog.execute()) { |
| return; |
| } |
| fInterpreterList.refresh(install); |
| } |
| |
| public IEnvironment getCurrentEnvironment() { |
| if (fEnvironments == null) { |
| return EnvironmentManager.getLocalEnvironment(); |
| } |
| return environments[fEnvironments.getSelectionIndex()]; |
| } |
| |
| public int getEnvironmentsCount() { |
| return environments.length; |
| } |
| |
| } |