/* * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jetbrains.python.packaging.ui; import com.google.common.collect.Sets; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.util.Consumer; import com.intellij.webcore.packaging.InstalledPackage; import com.intellij.webcore.packaging.InstalledPackagesPanel; import com.intellij.webcore.packaging.PackagesNotificationPanel; import com.jetbrains.python.packaging.*; import com.jetbrains.python.sdk.PySdkUtil; import com.jetbrains.python.sdk.PythonSdkType; import com.jetbrains.python.sdk.flavors.IronPythonSdkFlavor; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Set; /** * @author yole */ public class PyInstalledPackagesPanel extends InstalledPackagesPanel { public static final String INSTALL_MANAGEMENT = "installManagement"; public static final String CREATE_VENV = "createVEnv"; private boolean myHasManagement = false; public PyInstalledPackagesPanel(Project project, PackagesNotificationPanel area) { super(project, area); } private Sdk getSelectedSdk() { PyPackageManagementService service = (PyPackageManagementService)myPackageManagementService; return service != null ? service.getSdk() : null; } public void updateNotifications(@Nullable final Sdk selectedSdk) { if (selectedSdk == null) { myNotificationArea.hide(); return; } final Application application = ApplicationManager.getApplication(); application.executeOnPooledThread(new Runnable() { @Override public void run() { PyPackageManager packageManager = PyPackageManager.getInstance(selectedSdk); myHasManagement = packageManager.hasManagement(false); application.invokeLater(new Runnable() { @Override public void run() { if (selectedSdk == getSelectedSdk()) { final PythonSdkFlavor flavor = PythonSdkFlavor.getFlavor(selectedSdk); final boolean invalid = PythonSdkType.isInvalid(selectedSdk); boolean allowCreateVirtualEnv = !(PythonSdkType.isRemote(selectedSdk) || flavor instanceof IronPythonSdkFlavor) && !PythonSdkType.isVirtualEnv(selectedSdk) && myNotificationArea.hasLinkHandler(CREATE_VENV); final String createVirtualEnvLink = "create new VirtualEnv"; myNotificationArea.hide(); if (!invalid) { String text = null; if (!myHasManagement) { myNotificationArea.addLinkHandler(INSTALL_MANAGEMENT, new Runnable() { @Override public void run() { final Sdk sdk = getSelectedSdk(); if (sdk != null) { installManagementTools(sdk); } myNotificationArea.removeLinkHandler(INSTALL_MANAGEMENT); updateNotifications(selectedSdk); } } ); } if (!myHasManagement) { text = "Python packaging tools not found. Install packaging tools"; } if (text != null) { if (allowCreateVirtualEnv) { text += " or " + createVirtualEnvLink; } myNotificationArea.showWarning(text); } } myInstallButton.setEnabled(!invalid && myHasManagement); } } }, ModalityState.any()); } }); } @Override protected Set getPackagesToPostpone() { return Sets.newHashSet("pip", "distutils", "setuptools"); } private void installManagementTools(@NotNull final Sdk sdk) { final PyPackageManagerUI ui = new PyPackageManagerUI(myProject, sdk, new PyPackageManagerUI.Listener() { @Override public void started() { myPackagesTable.setPaintBusy(true); } @Override public void finished(List exceptions) { myPackagesTable.setPaintBusy(false); PyPackageManager packageManager = PyPackageManager.getInstance(sdk); if (!exceptions.isEmpty()) { final String firstLine = "Install Python packaging tools failed. "; final String description = PyPackageManagerUI.createDescription(exceptions, firstLine); PackagesNotificationPanel.showError(myProject, "Failed to install Python packaging tools", description); } packageManager.refresh(); updatePackages(new PyPackageManagementService(myProject, sdk)); for (Consumer listener : myPathChangedListeners) { listener.consume(sdk); } updateNotifications(sdk); } }); ui.installManagement(); } @Override protected boolean canUninstallPackage(InstalledPackage pkg) { if (!myHasManagement) return false; if (PythonSdkType.isVirtualEnv(getSelectedSdk()) && pkg instanceof PyPackage) { final String location = ((PyPackage)pkg).getLocation(); if (location != null && location.startsWith(PySdkUtil.getUserSite())) { return false; } } final String name = pkg.getName(); if (PyPackageManager.PACKAGE_PIP.equals(name) || PyPackageManager.PACKAGE_SETUPTOOLS.equals(name) || PyPackageManager.PACKAGE_DISTRIBUTE.equals(name)) { return false; } return true; } @Override protected boolean canUpgradePackage(InstalledPackage pyPackage) { return myHasManagement; } }