From 6820fe5453d2fc074aea6dd820f1240ba218b755 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Fri, 7 Feb 2014 18:59:46 +0400 Subject: [PATCH] added options for the details button --- .../impl/SdkConfigurationUtil.java | 27 +++++- .../PyActiveSdkConfigurable.java | 45 +++++++-- .../configuration/PythonSdkConfigurable.java | 2 +- ...erPathChooser.java => DetailsChooser.java} | 95 ++++++------------- .../jetbrains/python/sdk/PythonSdkType.java | 2 +- 5 files changed, 92 insertions(+), 79 deletions(-) rename python/src/com/jetbrains/python/sdk/{InterpreterPathChooser.java => DetailsChooser.java} (56%) diff --git a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java index bd3be406ef00..a076101072fa 100644 --- a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java +++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java @@ -54,7 +54,7 @@ public class SdkConfigurationUtil { public static void createSdk(@Nullable final Project project, final Sdk[] existingSdks, - final NullableConsumer onSdkCreatedCallBack, + final NullableConsumer onSdkCreatedCallBack, final boolean createIfExists, final SdkType... sdkTypes) { if (sdkTypes.length == 0) { onSdkCreatedCallBack.consume(null); @@ -72,8 +72,19 @@ public class SdkConfigurationUtil { @Override public void consume(List selectedFiles) { for (SdkType sdkType : sdkTypes) { - if (sdkType.isValidSdkHome(selectedFiles.get(0).getPath())) { - onSdkCreatedCallBack.consume(setupSdk(existingSdks, selectedFiles.get(0), sdkType, false, null, null)); + final String path = selectedFiles.get(0).getPath(); + if (sdkType.isValidSdkHome(path)) { + Sdk newSdk = null; + if (!createIfExists) { + for (Sdk sdk : existingSdks) { + if (path.equals(sdk.getHomePath())) { + newSdk = sdk; + } + } + } + if (newSdk == null) + newSdk = setupSdk(existingSdks, selectedFiles.get(0), sdkType, false, null, null); + onSdkCreatedCallBack.consume(newSdk); return; } } @@ -85,6 +96,14 @@ public class SdkConfigurationUtil { onSdkCreatedCallBack.consume(null); } }); + + } + + public static void createSdk(@Nullable final Project project, + final Sdk[] existingSdks, + final NullableConsumer onSdkCreatedCallBack, + final SdkType... sdkTypes) { + createSdk(project, existingSdks, onSdkCreatedCallBack, true, sdkTypes); } private static FileChooserDescriptor createCompositeDescriptor(final SdkType... sdkTypes) { @@ -140,7 +159,7 @@ public class SdkConfigurationUtil { final ProjectJdkImpl sdk; try { String sdkPath = sdkType.sdkPath(homeDir); - + final String sdkName = customSdkSuggestedName == null ? createUniqueSdkName(sdkType, sdkPath, sdksList) : createUniqueSdkName(customSdkSuggestedName, sdksList); diff --git a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java index 807c8af0edd6..917dec969476 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java +++ b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java @@ -35,11 +35,14 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CollectionComboBoxModel; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.NullableConsumer; import com.intellij.util.ui.UIUtil; import com.intellij.webcore.packaging.PackagesNotificationPanel; import com.jetbrains.python.packaging.ui.PyInstalledPackagesPanel; import com.jetbrains.python.packaging.ui.PyPackageManagementService; import com.jetbrains.python.psi.LanguageLevel; +import com.jetbrains.python.sdk.DetailsChooser; import com.jetbrains.python.sdk.PySdkListCellRenderer; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; import icons.PythonIcons; @@ -62,6 +65,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { private ProjectSdksModel myProjectSdksModel; private ComboBox mySdkCombo; private PyInstalledPackagesPanel myPackagesPanel; + private JButton myDetailsButton; public PyActiveSdkConfigurable(@NotNull Project project) { myModule = null; @@ -89,10 +93,36 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { @Override public void actionPerformed(ActionEvent e) { final Sdk selectedSdk = (Sdk)mySdkCombo.getSelectedItem(); - myPackagesPanel.updatePackages(selectedSdk == null ? null : new PyPackageManagementService(myProject, selectedSdk)); + if (selectedSdk != null) + myPackagesPanel.updatePackages(new PyPackageManagementService(myProject, selectedSdk)); } }); + myDetailsButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + DetailsChooser.show(myProject, myProjectSdksModel.getSdks(), + RelativePoint.fromScreen(myDetailsButton.getLocationOnScreen()), true, + new NullableConsumer() { + @Override + public void consume(Sdk sdk) { + if (sdk == null) return; + final Sdk existedSdk = myProjectSdksModel.findSdk(sdk.getName()); + if (existedSdk == null) { + myProjectSdksModel.addSdk(sdk); + } + myInterpreterList.setSelectedSdk(sdk); + + mySdkCombo.getModel().setSelectedItem(sdk); + myPackagesPanel + .updatePackages(new PyPackageManagementService(myProject, sdk)); + } + } + ); + } + } + ); + } private void layoutPanel() { @@ -107,12 +137,12 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { final JComponent notificationsComponent = notificationsArea.getComponent(); notificationsComponent.setPreferredSize(new Dimension(500, 29)); - JButton detailsButton = new JButton(); - detailsButton.setIcon(PythonIcons.Python.InterpreterGear); - detailsButton.setIconTextGap(0); - detailsButton.setPreferredSize(new Dimension(29, 29)); + myDetailsButton = new JButton(); + myDetailsButton.setIcon(PythonIcons.Python.InterpreterGear); + myDetailsButton.setIconTextGap(0); + myDetailsButton.setPreferredSize(new Dimension(29, 29)); if (((UIUtil.isUnderAquaLookAndFeel())) || UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula()) { - detailsButton.putClientProperty("JButton.buttonType", "square"); + myDetailsButton.putClientProperty("JButton.buttonType", "square"); } myPackagesPanel = new PyInstalledPackagesPanel(myProject, notificationsArea); @@ -134,7 +164,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { c.gridx = 2; c.gridy = 0; c.weightx = 0.0; - myPanel.add(detailsButton, c); + myPanel.add(myDetailsButton, c); c.insets = new Insets(2,2,2,2); c.gridx = 0; @@ -183,6 +213,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { @Override public void apply() throws ConfigurationException { + myProjectSdksModel.apply(); final Sdk selectedSdk = myProjectSdksModel.findSdk((Sdk)mySdkCombo.getSelectedItem()); if (myModule == null) { final ProjectRootManager rootManager = ProjectRootManager.getInstance(myProject); diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java index abdfd47e64e3..8f5233712aac 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java +++ b/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java @@ -365,7 +365,7 @@ public class PythonSdkConfigurable implements Configurable, Configurable.NoScrol } private void addSdk(AnActionButton button) { - InterpreterPathChooser + DetailsChooser .show(myProject, myProjectSdksModel.getSdks(), button.getPreferredPopupPoint(), false, new NullableConsumer() { @Override public void consume(Sdk sdk) { diff --git a/python/src/com/jetbrains/python/sdk/InterpreterPathChooser.java b/python/src/com/jetbrains/python/sdk/DetailsChooser.java similarity index 56% rename from python/src/com/jetbrains/python/sdk/InterpreterPathChooser.java rename to python/src/com/jetbrains/python/sdk/DetailsChooser.java index ab57e352a5b1..46e4adaa8a3c 100644 --- a/python/src/com/jetbrains/python/sdk/InterpreterPathChooser.java +++ b/python/src/com/jetbrains/python/sdk/DetailsChooser.java @@ -23,100 +23,75 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.ui.popup.ListPopup; -import com.intellij.openapi.ui.popup.ListPopupStep; -import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.*; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.NullableConsumer; -import com.intellij.util.SystemProperties; import com.jetbrains.python.remote.PythonRemoteInterpreterManager; -import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.List; /** * @author yole */ -public class InterpreterPathChooser extends BaseListPopupStep { +public class DetailsChooser extends BaseListPopupStep { private final Project myProject; private final Component myOwnerComponent; private final Sdk[] myExistingSdks; private final NullableConsumer myCallback; - private static final String LOCAL = "Local..."; - private static final String REMOTE = "Remote..."; - private static final String VIRTUALENV = "Create VirtualEnv..."; + private static final String LOCAL = "Add Local"; + private static final String REMOTE = "Add Remote"; + private static final String VIRTUALENV = "Create VirtualEnv"; + private static final String MORE = "More..."; public static void show(final Project project, final Sdk[] existingSdks, final RelativePoint popupPoint, - final boolean showVirtualEnv, + final boolean showMore, final NullableConsumer callback) { - ListPopupStep sdkHomesStep = new InterpreterPathChooser(project, popupPoint.getComponent(), existingSdks, showVirtualEnv, callback); + final ListPopupStep sdkHomesStep = new DetailsChooser(project, popupPoint.getComponent(), existingSdks, showMore, callback); final ListPopup popup = JBPopupFactory.getInstance().createListPopup(sdkHomesStep); popup.show(popupPoint); } - public InterpreterPathChooser(Project project, - Component ownerComponent, - Sdk[] existingSdks, - boolean showVirtualEnv, - NullableConsumer callback) { - super("Select Interpreter Path", getSuggestedPythonSdkPaths(existingSdks, showVirtualEnv)); + public DetailsChooser(Project project, + Component ownerComponent, + Sdk[] existingSdks, + boolean showMore, + NullableConsumer callback) { + super(null, getAvailableOptions(showMore)); myProject = project; myOwnerComponent = ownerComponent; myExistingSdks = existingSdks; myCallback = callback; } - private static List getSuggestedPythonSdkPaths(Sdk[] existingSdks, boolean showVirtualEnv) { - List paths = new ArrayList(); - Collection sdkHomes = PythonSdkType.getInstance().suggestHomePaths(); - for (String sdkHome : SdkConfigurationUtil.filterExistingPaths(PythonSdkType.getInstance(), sdkHomes, existingSdks)) { - paths.add(FileUtil.getLocationRelativeToUserHome(sdkHome)); - } - paths.add(LOCAL); + private static List getAvailableOptions(boolean showMore) { + final List options = new ArrayList(); + options.add(LOCAL); if (PythonRemoteInterpreterManager.getInstance() != null) { - paths.add(REMOTE); + options.add(REMOTE); } - if (showVirtualEnv) { - paths.add(VIRTUALENV); + options.add(VIRTUALENV); + + if (showMore) { + options.add(MORE); } - return paths; + return options; } @Nullable @Override - public Icon getIconFor(String aValue) { - if (LOCAL.equals(aValue) || REMOTE.equals(aValue) || VIRTUALENV.equals(aValue)) return null; - String filePath = aValue; - if (StringUtil.startsWithChar(filePath, '~')) { - String home = SystemProperties.getUserHome(); - filePath = home + filePath.substring(1); - } - final PythonSdkFlavor flavor = PythonSdkFlavor.getPlatformIndependentFlavor(filePath); - return flavor != null ? flavor.getIcon() : PythonSdkType.getInstance().getIcon(); + public ListSeparator getSeparatorAbove(String value) { + return MORE.equals(value) ? new ListSeparator() : null; } - @NotNull - @Override - public String getTextFor(String value) { - return FileUtil.toSystemDependentName(value); - } - - private void sdkSelected(final String selectedValue) { + private void optionSelected(final String selectedValue) { if (LOCAL.equals(selectedValue)) { createLocalSdk(); } @@ -127,7 +102,7 @@ public class InterpreterPathChooser extends BaseListPopupStep { createVirtualEnvSdk(); } else { - createSdkFromPath(selectedValue); + //createSdkFromPath(selectedValue); } } @@ -135,7 +110,7 @@ public class InterpreterPathChooser extends BaseListPopupStep { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - SdkConfigurationUtil.createSdk(myProject, myExistingSdks, myCallback, PythonSdkType.getInstance()); + SdkConfigurationUtil.createSdk(myProject, myExistingSdks, myCallback, false, PythonSdkType.getInstance()); } }, ModalityState.any()); } @@ -152,18 +127,6 @@ public class InterpreterPathChooser extends BaseListPopupStep { } } - private void createSdkFromPath(String selectedPath) { - String filePath = selectedPath; - if (StringUtil.startsWithChar(filePath, '~')) { - String home = SystemProperties.getUserHome(); - filePath = home + filePath.substring(1); - } - Sdk sdk = SdkConfigurationUtil.setupSdk(myExistingSdks, - LocalFileSystem.getInstance().findFileByPath(filePath), - PythonSdkType.getInstance(), false, null, null); - myCallback.consume(sdk); - } - private void createVirtualEnvSdk() { final CreateVirtualEnvDialog dialog; final List allSdks = Arrays.asList(myExistingSdks); @@ -193,7 +156,7 @@ public class InterpreterPathChooser extends BaseListPopupStep { public PopupStep onChosen(final String selectedValue, boolean finalChoice) { return doFinalStep(new Runnable() { public void run() { - sdkSelected(selectedValue); + optionSelected(selectedValue); } }); } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index cb5f855e309f..d0d910d3b4bb 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -277,7 +277,7 @@ public class PythonSdkType extends SdkType { public void showCustomCreateUI(SdkModel sdkModel, final JComponent parentComponent, final Consumer sdkCreatedCallback) { Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent)); - InterpreterPathChooser.show(project, sdkModel.getSdks(), RelativePoint.getCenterOf(parentComponent), true, new NullableConsumer() { + DetailsChooser.show(project, sdkModel.getSdks(), RelativePoint.getCenterOf(parentComponent), true, new NullableConsumer() { @Override public void consume(@Nullable Sdk sdk) { if (sdk != null) {