"Add interpreter" shows list of interpreters which are detected but haven't been...
authorDmitry Jemerov <yole@jetbrains.com>
Thu, 8 Jul 2010 17:21:08 +0000 (21:21 +0400)
committerDmitry Jemerov <yole@jetbrains.com>
Thu, 8 Jul 2010 17:24:48 +0000 (21:24 +0400)
platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java
platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java

index b4a7a956d098a9c2a13ba824bb555577f53a919f..2781f1b45ff033bf7b7a7f395157d83926a55e45 100644 (file)
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
@@ -43,6 +44,11 @@ public abstract class SdkType {
   @Nullable
   public abstract String suggestHomePath();
 
+  public Collection<String> suggestHomePaths() {
+    String s = suggestHomePath();
+    return s == null ? Collections.<String>emptyList() : Collections.singletonList(s);
+  }
+
   /**
    * If a path selected in the file chooser is not a valid SDK home path, returns an adjusted version of the path that is again
    * checked for validity.
index 4b23325081bd634b64f186330064adf17c956d2d..02781b67985f2fc1e72aa352bc73585366a5861d 100644 (file)
@@ -17,6 +17,7 @@
 package com.intellij.openapi.projectRoots.impl;
 
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.fileChooser.FileChooser;
 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
 import com.intellij.openapi.fileChooser.FileChooserDialog;
@@ -34,13 +35,21 @@ import com.intellij.openapi.roots.ModifiableRootModel;
 import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.roots.ProjectRootManager;
 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.util.BaseListPopupStep;
 import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import javax.swing.*;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
@@ -248,4 +257,78 @@ public class SdkConfigurationUtil {
     if (homepath == null) return null;
     return LocalFileSystem.getInstance().findFileByPath(homepath);
   }
+
+  public static void suggestAndAddSdk(final Project project,
+                                       SdkType sdkType,
+                                       final Sdk[] existingSdks,
+                                       JComponent popupOwner,
+                                       Consumer<Sdk> callback) {
+    Collection<String> sdkHomes = sdkType.suggestHomePaths();
+    List<String> suggestedSdkHomes = filterExistingPaths(sdkType, sdkHomes, existingSdks);
+    if (suggestedSdkHomes.size() > 0) {
+      suggestedSdkHomes.add(null);
+      showSuggestedHomesPopup(project, sdkType, existingSdks, suggestedSdkHomes, popupOwner, callback);
+    }
+    else {
+      Sdk sdk = createSdk(project, existingSdks, sdkType);
+      callback.consume(sdk);
+    }
+  }
+
+  private static void showSuggestedHomesPopup(final Project project,
+                                              final SdkType sdkType,
+                                              final Sdk[] existingSdks,
+                                              List<String> suggestedSdkHomes,
+                                              JComponent popupOwner,
+                                              final Consumer<Sdk> callback) {
+    ListPopupStep sdkHomesStep = new BaseListPopupStep<String>("Select Interpreter Path", suggestedSdkHomes) {
+      @NotNull
+      @Override
+      public String getTextFor(String value) {
+        return value == null ? "Specify Other..." : FileUtil.toSystemDependentName(value);
+      }
+
+      @Override
+      public PopupStep onChosen(String selectedValue, boolean finalChoice) {
+        if (selectedValue == null) {
+          ApplicationManager.getApplication().invokeLater(new Runnable() {
+            @Override
+            public void run() {
+              Sdk sdk = createSdk(project, existingSdks, sdkType);
+              callback.consume(sdk);
+            }
+          }, ModalityState.current());
+        }
+        else {
+          Sdk sdk = setupSdk(existingSdks, LocalFileSystem.getInstance().findFileByPath(selectedValue),
+                                                  sdkType, false, null, null);
+          callback.consume(sdk);
+        }
+        return FINAL_CHOICE;
+      }
+    };
+    final ListPopup popup = JBPopupFactory.getInstance().createListPopup(sdkHomesStep);
+    popup.showUnderneathOf(popupOwner);
+  }
+
+  private static List<String> filterExistingPaths(SdkType sdkType, Collection<String> sdkHomes, final Sdk[] sdks) {
+    List<String> result = new ArrayList<String>();
+    for (String sdkHome : sdkHomes) {
+      if (findByPath(sdkType, sdks, sdkHome) == null) {
+        result.add(sdkHome);
+      }
+    }
+    return result;
+  }
+
+  @Nullable
+  private static Sdk findByPath(SdkType sdkType, Sdk[] sdks, String sdkHome) {
+    for (Sdk sdk : sdks) {
+      if (sdk.getSdkType() == sdkType &&
+          FileUtil.pathsEqual(FileUtil.toSystemIndependentName(sdk.getHomePath()), FileUtil.toSystemIndependentName(sdkHome))) {
+        return sdk;
+      }
+    }
+    return null;
+  }
 }