From 9ba6a767a310f8b8e4dd1634fd5e9c8da177f7e2 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Tue, 10 Oct 2017 05:15:37 +0300 Subject: [PATCH] PY-22324 Reverted new project UI to single combo box to make it more consistent with UI for existing project Creation of virtualenvs is still lazy and allows creating virtualenvs just after the project folder is created. But new virtualenv is not the default choice at the moment. We'll come back to this idea later. --- .../steps/ProjectSpecificSettingsStep.java | 87 +++++-------------- .../newProject/steps/PyAddExistingSdkPanel.kt | 6 +- .../steps/PythonSdkChooserCombo.java | 40 ++++++--- .../src/com/jetbrains/python/sdk/PyLazySdk.kt | 5 +- .../python/sdk/PySdkListCellRenderer.kt | 8 +- .../python/sdk/PythonSdkDetailsStep.java | 25 ++++-- .../jetbrains/python/sdk/PythonSdkType.java | 2 +- .../python/sdk/add/PyAddNewVirtualEnvPanel.kt | 34 ++++---- .../python/sdk/add/PyAddSdkDialog.kt | 10 +-- .../python/sdk/flavors/PythonSdkFlavor.java | 2 +- 10 files changed, 97 insertions(+), 122 deletions(-) diff --git a/python/python-community-configure/src/com/jetbrains/python/newProject/steps/ProjectSpecificSettingsStep.java b/python/python-community-configure/src/com/jetbrains/python/newProject/steps/ProjectSpecificSettingsStep.java index fcfac3a74b8d..710398a3b3ca 100644 --- a/python/python-community-configure/src/com/jetbrains/python/newProject/steps/ProjectSpecificSettingsStep.java +++ b/python/python-community-configure/src/com/jetbrains/python/newProject/steps/ProjectSpecificSettingsStep.java @@ -22,7 +22,6 @@ import com.intellij.ide.util.projectWizard.ProjectSettingsStepBase; import com.intellij.ide.util.projectWizard.WebProjectTemplate; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.ui.LabeledComponent; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.ui.VerticalFlowLayout; @@ -35,6 +34,7 @@ import com.intellij.util.Consumer; import com.intellij.util.ObjectUtils; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.update.UiNotifyConnector; import com.jetbrains.python.configuration.PyConfigurableInterpreterList; import com.jetbrains.python.newProject.PyFrameworkProjectGenerator; @@ -42,28 +42,20 @@ import com.jetbrains.python.newProject.PythonProjectGenerator; import com.jetbrains.python.packaging.PyPackage; import com.jetbrains.python.packaging.PyPackageUtil; import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.sdk.PreferredSdkComparator; -import com.jetbrains.python.sdk.PyLazySdk; -import com.jetbrains.python.sdk.PySdkExtKt; -import com.jetbrains.python.sdk.PythonSdkType; -import com.jetbrains.python.sdk.add.PyAddNewVirtualEnvPanel; -import com.jetbrains.python.sdk.add.PyAddSdkGroupPanel; -import com.jetbrains.python.sdk.add.PyAddSdkPanel; +import com.jetbrains.python.sdk.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; -import java.awt.*; import java.io.File; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase implements DumbAware { private boolean myInstallFramework; - @Nullable private PyAddSdkGroupPanel myInterpreterPanel; + @Nullable private PyAddExistingSdkPanel myInterpreterPanel; public ProjectSpecificSettingsStep(@NotNull final DirectoryProjectGenerator projectGenerator, @NotNull final AbstractNewProjectStep.AbstractCallback callback) { @@ -105,25 +97,14 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i @Nullable public Sdk getSdk() { if (!(myProjectGenerator instanceof PythonProjectGenerator)) return null; - final PyAddSdkGroupPanel interpreterPanel = myInterpreterPanel; + final PyAddExistingSdkPanel interpreterPanel = myInterpreterPanel; if (interpreterPanel == null) return null; - final PyAddSdkPanel panel = interpreterPanel.getSelectedPanel(); - if (panel instanceof PyAddNewVirtualEnvPanel) { - final PyAddNewVirtualEnvPanel virtualEnvPanel = (PyAddNewVirtualEnvPanel)panel; - return new PyLazySdk("Uninitialized virtual environment at " + virtualEnvPanel.getPath(), - virtualEnvPanel::getOrCreateSdk); - } - else if (panel instanceof PyAddExistingSdkPanel) { - return panel.getSdk(); - } - else { - return null; - } + return interpreterPanel.getSdk(); } @Nullable private Sdk getInterpreterPanelSdk() { - final PyAddSdkGroupPanel interpreterPanel = myInterpreterPanel; + final PyAddExistingSdkPanel interpreterPanel = myInterpreterPanel; if (interpreterPanel == null) return null; return interpreterPanel.getSdk(); } @@ -140,7 +121,7 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i final String fileName = PathUtil.getFileName(getNewProjectPath()); ((PythonProjectGenerator)myProjectGenerator).locationChanged(fileName); }); - final PyAddSdkGroupPanel interpreterPanel = myInterpreterPanel; + final PyAddExistingSdkPanel interpreterPanel = myInterpreterPanel; if (interpreterPanel != null) { UiNotifyConnector.doWhenFirstShown(interpreterPanel, this::checkValid); } @@ -152,11 +133,9 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i */ @Nullable final String getRemotePath() { - final PyAddSdkGroupPanel interpreterPanel = myInterpreterPanel; + final PyAddExistingSdkPanel interpreterPanel = myInterpreterPanel; if (interpreterPanel == null) return null; - final PyAddExistingSdkPanel panel = ObjectUtils.tryCast(interpreterPanel.getSelectedPanel(), PyAddExistingSdkPanel.class); - if (panel == null) return null; - return panel.getRemotePath(); + return interpreterPanel.getRemotePath(); } @Override @@ -175,7 +154,7 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i return false; } - final PyAddSdkGroupPanel interpreterPanel = myInterpreterPanel; + final PyAddExistingSdkPanel interpreterPanel = myInterpreterPanel; if (interpreterPanel != null) { final List validationInfos = interpreterPanel.validateAll(); if (!validationInfos.isEmpty()) { @@ -187,7 +166,7 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i final PythonProjectGenerator generator = ObjectUtils.tryCast(myProjectGenerator, PythonProjectGenerator.class); final Sdk sdk = getInterpreterPanelSdk(); - if (generator == null || sdk == null) return true; + if (generator == null || sdk == null || sdk instanceof PyLazySdk) return true; try { generator.checkProjectCanBeCreatedOnSdk(sdk, new File(myLocationField.getText())); @@ -260,17 +239,9 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i @Override protected JPanel createBasePanel() { if (myProjectGenerator instanceof PythonProjectGenerator) { - final BorderLayout layout = new BorderLayout(); - - final JPanel locationPanel = new JPanel(layout); - final JPanel panel = new JPanel(new VerticalFlowLayout(0, 2)); - final LabeledComponent location = createLocationComponent(); - - locationPanel.add(location, BorderLayout.CENTER); - panel.add(locationPanel); - panel.add(createInterpretersPanel()); - + final JPanel interpretersPanel = createInterpretersPanel(); + panel.add(interpretersPanel); final JPanel basePanelExtension = ((PythonProjectGenerator)myProjectGenerator).extendBasePanel(); if (basePanelExtension != null) { panel.add(basePanelExtension); @@ -283,35 +254,22 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i @NotNull private JPanel createInterpretersPanel() { - final JPanel container = new JPanel(new BorderLayout()); - final JPanel decoratorPanel = new JPanel(new VerticalFlowLayout()); - final List existingSdks = getValidPythonSdks(); final Sdk preferredSdk = getPreferredSdk(existingSdks); + final FormBuilder formBuilder = FormBuilder.createFormBuilder(); + formBuilder.addLabeledComponent("Location:", createLocationComponent().getComponent()); + final String newProjectPath = getNewProjectPath(); - final PyAddNewVirtualEnvPanel newVirtualEnvPanel = new PyAddNewVirtualEnvPanel(null, existingSdks, newProjectPath); - final PyAddExistingSdkPanel existingSdkPanel = new PyAddExistingSdkPanel(null, existingSdks, newProjectPath, preferredSdk); - final HideableDecorator decorator = new HideableDecorator(decoratorPanel, getProjectInterpreterTitle(newVirtualEnvPanel), false); - decorator.setContentComponent(container); + final PyAddExistingSdkPanel existingSdkPanel = new PyAddExistingSdkPanel(null, existingSdks, newProjectPath, preferredSdk, formBuilder); - final List panels = Arrays.asList(newVirtualEnvPanel, existingSdkPanel); - myInterpreterPanel = new PyAddSdkGroupPanel("New project interpreter", getIcon(), panels, newVirtualEnvPanel); - myInterpreterPanel.addChangeListener(() -> decorator.setTitle(getProjectInterpreterTitle(myInterpreterPanel.getSelectedPanel()))); + myInterpreterPanel = existingSdkPanel; - newVirtualEnvPanel.addChangeListener(this::checkValid); existingSdkPanel.addChangeListener(this::checkValid); - myInterpreterPanel.addChangeListener(this::checkValid); + addLocationChangeListener(e -> myInterpreterPanel.setNewProjectPath(getNewProjectPath())); - addLocationChangeListener(event -> { - final String path = getNewProjectPath(); - newVirtualEnvPanel.setNewProjectPath(path); - existingSdkPanel.setNewProjectPath(path); - }); - - container.add(myInterpreterPanel, BorderLayout.NORTH); - return decoratorPanel; + return existingSdkPanel; } @NotNull @@ -332,11 +290,6 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase i }); } - @NotNull - private static String getProjectInterpreterTitle(@NotNull PyAddSdkPanel panel) { - return "Project Interpreter: " + StringUtil.toTitleCase(panel.getPanelName()); - } - @Nullable private Sdk getPreferredSdk(@NotNull List sdks) { final PyFrameworkProjectGenerator projectGenerator = ObjectUtils.tryCast(getProjectGenerator(), PyFrameworkProjectGenerator.class); diff --git a/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PyAddExistingSdkPanel.kt b/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PyAddExistingSdkPanel.kt index b04266a847c8..1f4d8ec172f1 100644 --- a/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PyAddExistingSdkPanel.kt +++ b/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PyAddExistingSdkPanel.kt @@ -29,7 +29,8 @@ import java.awt.Component class PyAddExistingSdkPanel(project: Project?, existingSdks: List, newProjectPath: String?, - preferredSdk: Sdk?) : PyAddSdkPanel() { + preferredSdk: Sdk?, + formBuilder: FormBuilder) : PyAddSdkPanel() { override val panelName = "Existing interpreter" @@ -56,7 +57,6 @@ class PyAddExistingSdkPanel(project: Project?, init { layout = BorderLayout() - // TODO: Set new project path on external change sdkChooserCombo = PythonSdkChooserCombo(project, existingSdks, newProjectPath, { it != null && it == preferredSdk }).apply { if (SystemInfo.isMac && !UIUtil.isUnderDarcula()) { putClientProperty("JButton.buttonType", null) @@ -66,7 +66,7 @@ class PyAddExistingSdkPanel(project: Project?, update() } } - val formPanel = FormBuilder.createFormBuilder() + val formPanel = formBuilder .addLabeledComponent("Interpreter:", sdkChooserCombo) .addComponent(remotePathField.mainPanel) .panel diff --git a/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PythonSdkChooserCombo.java b/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PythonSdkChooserCombo.java index b13056caecda..e381638410e7 100644 --- a/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PythonSdkChooserCombo.java +++ b/python/python-community-configure/src/com/jetbrains/python/newProject/steps/PythonSdkChooserCombo.java @@ -27,6 +27,7 @@ import com.intellij.ui.ComboboxSpeedSearch; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.configuration.PyConfigurableInterpreterList; +import com.jetbrains.python.sdk.PyLazySdk; import com.jetbrains.python.sdk.PySdkListCellRenderer; import com.jetbrains.python.sdk.PythonSdkDetailsStep; import org.jetbrains.annotations.NotNull; @@ -35,6 +36,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; import java.util.List; /** @@ -85,20 +87,36 @@ public class PythonSdkChooserCombo extends ComboboxWithBrowseButton { final Sdk oldSelectedSdk = (Sdk)comboBox.getSelectedItem(); PythonSdkDetailsStep.show(project, sdks, null, this, getButton().getLocationOnScreen(), myNewProjectPath, sdk -> { if (sdk == null) return; - final ProjectSdksModel projectSdksModel = interpreterList.getModel(); - if (projectSdksModel.findSdk(sdk) == null) { - projectSdksModel.addSdk(sdk); - try { - projectSdksModel.apply(); - } - catch (ConfigurationException e) { - LOG.error("Error adding new python interpreter " + e.getMessage()); + if (!(sdk instanceof PyLazySdk)) { + final ProjectSdksModel projectSdksModel = interpreterList.getModel(); + if (projectSdksModel.findSdk(sdk) == null) { + projectSdksModel.addSdk(sdk); + try { + projectSdksModel.apply(); + } + catch (ConfigurationException e) { + LOG.error("Error adding new python interpreter " + e.getMessage()); + } } } - final List committedSdks = interpreterList.getAllPythonSdks(); + final List allSdks = new ArrayList<>(); + if (sdk instanceof PyLazySdk) { + allSdks.add(sdk); + } + // TODO: Filter out and sort the interpreters list + allSdks.addAll(interpreterList.getAllPythonSdks()); final Sdk copiedSdk = interpreterList.getModel().findSdk(sdk.getName()); - comboBox.setModel(new CollectionComboBoxModel<>(committedSdks, oldSelectedSdk)); - comboBox.setSelectedItem(copiedSdk); + final Sdk selectedSdk; + if (sdk instanceof PyLazySdk) { + selectedSdk = sdk; + } + else if (copiedSdk != null) { + selectedSdk = copiedSdk; + } + else { + selectedSdk = oldSelectedSdk; + } + comboBox.setModel(new CollectionComboBoxModel<>(allSdks, selectedSdk)); }); } diff --git a/python/src/com/jetbrains/python/sdk/PyLazySdk.kt b/python/src/com/jetbrains/python/sdk/PyLazySdk.kt index 9ca7b1b5503e..ee68364f85ac 100644 --- a/python/src/com/jetbrains/python/sdk/PyLazySdk.kt +++ b/python/src/com/jetbrains/python/sdk/PyLazySdk.kt @@ -18,10 +18,13 @@ package com.jetbrains.python.sdk import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl import com.intellij.openapi.util.NullableComputable +import javax.swing.Icon /** * @author vlan */ -class PyLazySdk(name: String, private val create: NullableComputable) : ProjectJdkImpl(name, PythonSdkType.getInstance(), null, null) { +class PyLazySdk(name: String, + val icon: Icon, + private val create: NullableComputable) : ProjectJdkImpl(name, PythonSdkType.getInstance(), null, null) { fun create(): Sdk? = create.compute() } diff --git a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.kt b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.kt index 3f982ba5727f..369e988a8bb1 100644 --- a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.kt +++ b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.kt @@ -74,11 +74,15 @@ open class PySdkListCellRenderer(private val sdkModifiers: Map sdk.icon + flavor != null -> flavor.icon + else -> (sdk.sdkType as? SdkType)?.icon ?: return null + } return when { PythonSdkType.isInvalid(sdk) || PythonSdkType.isIncompleteRemote(sdk) || PythonSdkType.hasInvalidRemoteCredentials(sdk) -> wrapIconWithWarningDecorator(icon) - sdk is PyDetectedSdk -> + sdk is PyDetectedSdk || sdk is PyLazySdk -> IconLoader.getTransparentIcon(icon) else -> icon diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java index 0aa85e5b1fda..b5bd96f24378 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkDetailsStep.java @@ -50,7 +50,7 @@ public class PythonSdkDetailsStep extends BaseListPopupStep { private static final String LOCAL = PyBundle.message("sdk.details.step.add.local"); private static final String REMOTE = PyBundle.message("sdk.details.step.add.remote"); private static final String ALL = PyBundle.message("sdk.details.step.show.all"); - @Nullable private String myNewProjectPath; + @Nullable private final String myNewProjectPath; public static void show(@Nullable final Project project, @NotNull final Sdk[] existingSdks, @@ -60,23 +60,24 @@ public class PythonSdkDetailsStep extends BaseListPopupStep { @Nullable String newProjectPath, @NotNull final NullableConsumer sdkAddedCallback) { final PythonSdkDetailsStep sdkHomesStep = new PythonSdkDetailsStep(project, showAllDialog, ownerComponent, existingSdks, - sdkAddedCallback); - sdkHomesStep.myNewProjectPath = newProjectPath; + sdkAddedCallback, newProjectPath); final ListPopup popup = JBPopupFactory.getInstance().createListPopup(sdkHomesStep); popup.showInScreenCoordinates(ownerComponent, popupPoint); } - public PythonSdkDetailsStep(@Nullable final Project project, - @Nullable final DialogWrapper showAllDialog, - @NotNull final Component ownerComponent, - @NotNull final Sdk[] existingSdks, - @NotNull final NullableConsumer sdkAddedCallback) { + private PythonSdkDetailsStep(@Nullable final Project project, + @Nullable final DialogWrapper showAllDialog, + @NotNull final Component ownerComponent, + @NotNull final Sdk[] existingSdks, + @NotNull final NullableConsumer sdkAddedCallback, + @Nullable String newProjectPath) { super(null, getAvailableOptions(showAllDialog != null)); myProject = project; myShowAll = showAllDialog; myOwnerComponent = ownerComponent; myExistingSdks = existingSdks; mySdkAddedCallback = sdkAddedCallback; + myNewProjectPath = newProjectPath; } private static List getAvailableOptions(boolean showAll) { @@ -114,7 +115,13 @@ public class PythonSdkDetailsStep extends BaseListPopupStep { private void createLocalSdk() { final Project project = myNewProjectPath != null ? null : myProject; final PyAddSdkDialog dialog = new PyAddSdkDialog(project, Arrays.asList(myExistingSdks), myNewProjectPath); - final Sdk sdk = dialog.showAndGet() ? dialog.getOrCreateSdk() : null; + final Sdk sdk; + if (dialog.showAndGet()) { + sdk = dialog.getOrCreateSdk(); + } + else { + sdk = null; + } mySdkAddedCallback.consume(sdk); } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index 97ec27e38807..2cc47ad81688 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -224,7 +224,7 @@ public final class PythonSdkType extends SdkType { } public static boolean isInvalid(@NotNull Sdk sdk) { - if (isRemote(sdk)) { + if (isRemote(sdk) || sdk instanceof PyLazySdk) { return false; } final VirtualFile interpreter = sdk.getHomeDirectory(); diff --git a/python/src/com/jetbrains/python/sdk/add/PyAddNewVirtualEnvPanel.kt b/python/src/com/jetbrains/python/sdk/add/PyAddNewVirtualEnvPanel.kt index c8e40468e799..7547b5c06eda 100644 --- a/python/src/com/jetbrains/python/sdk/add/PyAddNewVirtualEnvPanel.kt +++ b/python/src/com/jetbrains/python/sdk/add/PyAddNewVirtualEnvPanel.kt @@ -29,19 +29,17 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.ui.TextFieldWithBrowseButton +import com.intellij.openapi.util.NullableComputable import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VfsUtil -import com.intellij.ui.DocumentAdapter import com.intellij.ui.components.JBCheckBox import com.intellij.util.PathUtil import com.intellij.util.SystemProperties import com.intellij.util.ui.FormBuilder import com.jetbrains.python.packaging.PyPackageManager import com.jetbrains.python.packaging.PyPackageService -import com.jetbrains.python.sdk.associateWithProject -import com.jetbrains.python.sdk.createSdkByGenerateTask -import com.jetbrains.python.sdk.findBaseSdks +import com.jetbrains.python.sdk.* import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor import icons.PythonIcons import org.jetbrains.annotations.SystemDependent @@ -50,24 +48,17 @@ import org.jetbrains.jps.model.serialization.PathMacroUtil import java.awt.BorderLayout import java.io.File import javax.swing.Icon -import javax.swing.event.DocumentEvent /** * @author vlan */ class PyAddNewVirtualEnvPanel(private val project: Project?, private val existingSdks: List, - newProjectPath: String?) : PyAddSdkPanel() { + private val newProjectPath: String?) : PyAddSdkPanel() { companion object { private const val VIRTUALENV_ROOT_DIR_MACRO_NAME = "VIRTUALENV_ROOT_DIR" } - var newProjectPath: String? = newProjectPath - set(value) { - field = value - pathField.text = defaultBasePath - } - val path: String get() = pathField.text.trim() @@ -101,6 +92,10 @@ class PyAddNewVirtualEnvPanel(private val project: Project?, .filterNotNull() override fun getOrCreateSdk(): Sdk? { + return if (newProjectPath != null) sdk else createSdk() + } + + private fun createSdk(): Sdk? { val root = pathField.text val task = object : Task.WithResult(project, "Creating Virtual Environment", false) { override fun compute(indicator: ProgressIndicator): String { @@ -121,14 +116,15 @@ class PyAddNewVirtualEnvPanel(private val project: Project?, return sdk } - fun addChangeListener(listener: Runnable) { - pathField.textField.document.addDocumentListener(object: DocumentAdapter() { - override fun textChanged(e: DocumentEvent?) { - listener.run() + override val sdk: Sdk? + get() { + val baseName = baseSdkField.selectedSdk?.homePath?.let { PythonSdkType.suggestBaseSdkName(it) } + val title = when { + baseName != null -> "New ${baseName} virtual environment" + else -> "New virtual environment" } - }) - baseSdkField.childComponent.addItemListener { listener.run() } - } + return PyLazySdk(title, PythonIcons.Python.Virtualenv, NullableComputable { createSdk() }) + } private fun excludeDirectoryFromProject(path: String, project: Project?) { val currentProject = project ?: findProjectFromFocus() ?: return diff --git a/python/src/com/jetbrains/python/sdk/add/PyAddSdkDialog.kt b/python/src/com/jetbrains/python/sdk/add/PyAddSdkDialog.kt index 39fd21458f60..8a22502965aa 100644 --- a/python/src/com/jetbrains/python/sdk/add/PyAddSdkDialog.kt +++ b/python/src/com/jetbrains/python/sdk/add/PyAddSdkDialog.kt @@ -24,7 +24,6 @@ import com.intellij.openapi.ui.popup.ListItemDescriptorAdapter import com.intellij.openapi.util.text.StringUtil import com.intellij.ui.components.JBList import com.intellij.ui.popup.list.GroupedItemsListRenderer -import com.intellij.util.PlatformUtils import com.intellij.util.ui.JBUI import com.jetbrains.python.sdk.PreferredSdkComparator import com.jetbrains.python.sdk.PythonSdkType @@ -101,18 +100,13 @@ class PyAddSdkDialog(private val project: Project?, private fun createVirtualEnvPanel(project: Project?, existingSdks: List, newProjectPath: String?): PyAddSdkPanel { - val newVirtualEnvPanel = if (project != null || PlatformUtils.isPyCharmEducational()) - PyAddNewVirtualEnvPanel(project, existingSdks, newProjectPath) - else - null + val newVirtualEnvPanel = PyAddNewVirtualEnvPanel(project, existingSdks, newProjectPath) val existingVirtualEnvPanel = PyAddExistingVirtualEnvPanel(project, existingSdks, newProjectPath) val panels = listOf(newVirtualEnvPanel, existingVirtualEnvPanel) - .filterNotNull() val defaultPanel = when { detectVirtualEnvs(project, existingSdks).any { it.isAssociatedWithProject(project) } -> existingVirtualEnvPanel - newVirtualEnvPanel != null -> newVirtualEnvPanel - else -> existingVirtualEnvPanel + else -> newVirtualEnvPanel } return PyAddSdkGroupPanel("Virtual environment", PythonIcons.Python.Virtualenv, panels, defaultPanel) } diff --git a/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java index 4b14768d7b21..b36f4fe2142f 100644 --- a/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/flavors/PythonSdkFlavor.java @@ -124,7 +124,7 @@ public abstract class PythonSdkFlavor { } @Nullable - public static PythonSdkFlavor getFlavor(Sdk sdk) { + public static PythonSdkFlavor getFlavor(@NotNull Sdk sdk) { final SdkAdditionalData data = sdk.getSdkAdditionalData(); if (data instanceof PythonSdkAdditionalData) { PythonSdkFlavor flavor = ((PythonSdkAdditionalData)data).getFlavor();