/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ /* * Created on Jan 25, 2005 * * @author Fabio Zadrozny */ package org.python.pydev.ui; import java.util.ArrayList; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; 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.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.dialogs.PropertyPage; import org.python.pydev.core.IInterpreterInfo; import org.python.pydev.core.IInterpreterManager; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.docutils.StringUtils; import org.python.pydev.core.log.Log; import org.python.pydev.plugin.PydevPlugin; import org.python.pydev.plugin.nature.PythonNature; import org.python.pydev.utils.ICallback; /** * @author Fabio Zadrozny */ public class PyProjectPythonDetails extends PropertyPage { /** * This class provides a way to show to the user the options available to configure a project with the * correct interpreter and grammar. */ public static class ProjectInterpreterAndGrammarConfig { private static final String INTERPRETER_NOT_CONFIGURED_MSG = "<a>Please configure an interpreter in the related preferences before proceeding.</a>"; public Button radioPy; public Button radioJy; public Button radioIron; public Combo comboGrammarVersion; public Label versionLabel; public Combo interpretersChoice; private Link interpreterNoteText; private SelectionListener selectionListener; private ICallback onSelectionChanged; private Label interpreterLabel; public ProjectInterpreterAndGrammarConfig() { } /** * Optionally, a callback may be passed to be called whenever the selection of the project type changes. */ public ProjectInterpreterAndGrammarConfig(ICallback callback) { this.onSelectionChanged = callback; } public Control doCreateContents(Composite p) { Composite topComp = new Composite(p, SWT.NONE); GridLayout innerLayout = new GridLayout(); innerLayout.numColumns = 1; innerLayout.marginHeight = 0; innerLayout.marginWidth = 0; topComp.setLayout(innerLayout); GridData gd = new GridData(GridData.FILL_BOTH); topComp.setLayoutData(gd); //Project type Group group = new Group(topComp, SWT.NONE); group.setText("Choose the project type"); GridLayout layout = new GridLayout(); layout.horizontalSpacing = 8; layout.numColumns = 3; group.setLayout(layout); gd = new GridData(GridData.FILL_HORIZONTAL); group.setLayoutData(gd); radioPy = new Button(group, SWT.RADIO | SWT.LEFT); radioPy.setText("Python"); radioJy = new Button(group, SWT.RADIO | SWT.LEFT); radioJy.setText("Jython"); radioIron = new Button(group, SWT.RADIO | SWT.LEFT); radioIron.setText("Iron Python"); //Grammar version versionLabel = new Label(topComp, 0); versionLabel.setText("Grammar Version"); gd = new GridData(GridData.FILL_HORIZONTAL); versionLabel.setLayoutData(gd); comboGrammarVersion = new Combo(topComp, SWT.READ_ONLY); for (String s : IPythonNature.Versions.VERSION_NUMBERS) { comboGrammarVersion.add(s); } gd = new GridData(GridData.FILL_HORIZONTAL); comboGrammarVersion.setLayoutData(gd); //Interpreter interpreterLabel = new Label(topComp, 0); interpreterLabel.setText("Interpreter"); gd = new GridData(GridData.FILL_HORIZONTAL); interpreterLabel.setLayoutData(gd); //interpreter configured in the project final String[] idToConfig = new String[] { "org.python.pydev.ui.pythonpathconf.interpreterPreferencesPagePython" }; interpretersChoice = new Combo(topComp, SWT.READ_ONLY); selectionListener = new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } /** * @param e can be null to force an update. */ public void widgetSelected(SelectionEvent e) { if (e != null) { Button source = (Button) e.getSource(); if (!source.getSelection()) { return; //we'll get 2 notifications: selection of one and deselection of the other, so, let's just treat the selection } } IInterpreterManager interpreterManager; if (radioJy.getSelection()) { interpreterManager = PydevPlugin.getJythonInterpreterManager(); } else if (radioIron.getSelection()) { interpreterManager = PydevPlugin.getIronpythonInterpreterManager(); } else { interpreterManager = PydevPlugin.getPythonInterpreterManager(); } IInterpreterInfo[] interpretersInfo = interpreterManager.getInterpreterInfos(); if (interpretersInfo.length > 0) { ArrayList<String> interpretersWithDefault = new ArrayList<String>(); interpretersWithDefault.add(IPythonNature.DEFAULT_INTERPRETER); for (IInterpreterInfo info : interpretersInfo) { interpretersWithDefault.add(info.getName()); } interpretersChoice.setItems(interpretersWithDefault.toArray(new String[0])); interpretersChoice.setVisible(true); interpreterNoteText.setText("<a>Click here to configure an interpreter not listed.</a>"); interpretersChoice.setText(IPythonNature.DEFAULT_INTERPRETER); } else { interpretersChoice.setVisible(false); interpreterNoteText.setText(INTERPRETER_NOT_CONFIGURED_MSG); } //config which preferences page should be opened! switch (interpreterManager.getInterpreterType()) { case IInterpreterManager.INTERPRETER_TYPE_PYTHON: idToConfig[0] = "org.python.pydev.ui.pythonpathconf.interpreterPreferencesPagePython"; break; case IInterpreterManager.INTERPRETER_TYPE_JYTHON: idToConfig[0] = "org.python.pydev.ui.pythonpathconf.interpreterPreferencesPageJython"; break; case IInterpreterManager.INTERPRETER_TYPE_IRONPYTHON: idToConfig[0] = "org.python.pydev.ui.pythonpathconf.interpreterPreferencesPageIronpython"; break; default: throw new RuntimeException("Cannot recognize type: " + interpreterManager.getInterpreterType()); } if (onSelectionChanged != null) { try { onSelectionChanged.call(null); } catch (Exception e1) { Log.log(e1); } } } }; gd = new GridData(GridData.FILL_HORIZONTAL); interpretersChoice.setLayoutData(gd); radioPy.addSelectionListener(selectionListener); radioJy.addSelectionListener(selectionListener); radioIron.addSelectionListener(selectionListener); interpreterNoteText = new Link(topComp, SWT.LEFT | SWT.WRAP); gd = new GridData(GridData.FILL_HORIZONTAL); interpreterNoteText.setLayoutData(gd); interpreterNoteText.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(null, idToConfig[0], null, null); dialog.open(); //just to re-update it again selectionListener.widgetSelected(null); } public void widgetDefaultSelected(SelectionEvent e) { } }); return topComp; } /** * @return a string as specified in the constants in IPythonNature * @see IPythonNature#PYTHON_VERSION_XXX * @see IPythonNature#JYTHON_VERSION_XXX * @see IPythonNature#IRONPYTHON_VERSION_XXX */ public String getSelectedPythonOrJythonAndGrammarVersion() { if (radioPy.getSelection()) { return "python " + comboGrammarVersion.getText(); } if (radioJy.getSelection()) { return "jython " + comboGrammarVersion.getText(); } if (radioIron.getSelection()) { return "ironpython " + comboGrammarVersion.getText(); } throw new RuntimeException("Some radio must be selected"); } public String getProjectInterpreter() { if (INTERPRETER_NOT_CONFIGURED_MSG.equals(interpreterNoteText.getText())) { return null; } return interpretersChoice.getText(); } public void setDefaultSelection() { radioPy.setSelection(true); comboGrammarVersion.setText(IPythonNature.Versions.LAST_VERSION_NUMBER); //Just to update things this.selectionListener.widgetSelected(null); } } /** * The element. */ public IAdaptable element; public ProjectInterpreterAndGrammarConfig projectConfig = new ProjectInterpreterAndGrammarConfig(); /* * (non-Javadoc) * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement() */ public IAdaptable getElement() { return element; } /** * Sets the element that owns properties shown on this page. * * @param element the element */ public void setElement(IAdaptable element) { this.element = element; } public IProject getProject() { return (IProject) getElement().getAdapter(IProject.class); } @Override public Control createContents(Composite p) { Control contents = projectConfig.doCreateContents(p); setSelected(); return contents; } private void setSelected() { PythonNature pythonNature = PythonNature.getPythonNature(getProject()); try { //Set whether it's Python/Jython String version = pythonNature.getVersion(); if (IPythonNature.Versions.ALL_PYTHON_VERSIONS.contains(version)) { projectConfig.radioPy.setSelection(true); } else if (IPythonNature.Versions.ALL_IRONPYTHON_VERSIONS.contains(version)) { projectConfig.radioIron.setSelection(true); } else if (IPythonNature.Versions.ALL_JYTHON_VERSIONS.contains(version)) { projectConfig.radioJy.setSelection(true); } //We must set the grammar version too (that's from a string in the format "Python 2.4" and we only want //the version). String v = StringUtils.split(version, ' ').get(1); projectConfig.comboGrammarVersion.setText(v); //Update interpreter projectConfig.selectionListener.widgetSelected(null); String configuredInterpreter = pythonNature.getProjectInterpreterName(); if (configuredInterpreter != null) { projectConfig.interpretersChoice.setText(configuredInterpreter); } } catch (CoreException e) { Log.log(e); } } protected void performApply() { doIt(); } public boolean performOk() { return doIt(); } private boolean doIt() { IProject project = getProject(); if (project != null) { PythonNature pythonNature = PythonNature.getPythonNature(project); try { String projectInterpreter = projectConfig.getProjectInterpreter(); if (projectInterpreter == null) { return false; } pythonNature.setVersion(projectConfig.getSelectedPythonOrJythonAndGrammarVersion(), projectInterpreter); } catch (CoreException e) { Log.log(e); } } return true; } }