added options for the details button

This commit is contained in:
Ekaterina Tuzova
2014-02-07 18:59:46 +04:00
parent 3787e1efe2
commit 6820fe5453
5 changed files with 92 additions and 79 deletions
@@ -54,7 +54,7 @@ public class SdkConfigurationUtil {
public static void createSdk(@Nullable final Project project,
final Sdk[] existingSdks,
final NullableConsumer<Sdk> onSdkCreatedCallBack,
final NullableConsumer<Sdk> 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<VirtualFile> 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<Sdk> 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);
@@ -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<Sdk>() {
@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);
@@ -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<Sdk>() {
@Override
public void consume(Sdk sdk) {
@@ -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<String> {
public class DetailsChooser extends BaseListPopupStep<String> {
private final Project myProject;
private final Component myOwnerComponent;
private final Sdk[] myExistingSdks;
private final NullableConsumer<Sdk> 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<Sdk> 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<Sdk> callback) {
super("Select Interpreter Path", getSuggestedPythonSdkPaths(existingSdks, showVirtualEnv));
public DetailsChooser(Project project,
Component ownerComponent,
Sdk[] existingSdks,
boolean showMore,
NullableConsumer<Sdk> callback) {
super(null, getAvailableOptions(showMore));
myProject = project;
myOwnerComponent = ownerComponent;
myExistingSdks = existingSdks;
myCallback = callback;
}
private static List<String> getSuggestedPythonSdkPaths(Sdk[] existingSdks, boolean showVirtualEnv) {
List<String> paths = new ArrayList<String>();
Collection<String> sdkHomes = PythonSdkType.getInstance().suggestHomePaths();
for (String sdkHome : SdkConfigurationUtil.filterExistingPaths(PythonSdkType.getInstance(), sdkHomes, existingSdks)) {
paths.add(FileUtil.getLocationRelativeToUserHome(sdkHome));
}
paths.add(LOCAL);
private static List<String> getAvailableOptions(boolean showMore) {
final List<String> options = new ArrayList<String>();
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<String> {
createVirtualEnvSdk();
}
else {
createSdkFromPath(selectedValue);
//createSdkFromPath(selectedValue);
}
}
@@ -135,7 +110,7 @@ public class InterpreterPathChooser extends BaseListPopupStep<String> {
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<String> {
}
}
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<Sdk> allSdks = Arrays.asList(myExistingSdks);
@@ -193,7 +156,7 @@ public class InterpreterPathChooser extends BaseListPopupStep<String> {
public PopupStep onChosen(final String selectedValue, boolean finalChoice) {
return doFinalStep(new Runnable() {
public void run() {
sdkSelected(selectedValue);
optionSelected(selectedValue);
}
});
}
@@ -277,7 +277,7 @@ public class PythonSdkType extends SdkType {
public void showCustomCreateUI(SdkModel sdkModel, final JComponent parentComponent, final Consumer<Sdk> sdkCreatedCallback) {
Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent));
InterpreterPathChooser.show(project, sdkModel.getSdks(), RelativePoint.getCenterOf(parentComponent), true, new NullableConsumer<Sdk>() {
DetailsChooser.show(project, sdkModel.getSdks(), RelativePoint.getCenterOf(parentComponent), true, new NullableConsumer<Sdk>() {
@Override
public void consume(@Nullable Sdk sdk) {
if (sdk != null) {