diff --git a/python/python-sdk-configurator/backend/resources/intellij.python.sdkConfigurator.backend.xml b/python/python-sdk-configurator/backend/resources/intellij.python.sdkConfigurator.backend.xml
index 09ccc3c3b20d..1ee5941f00c6 100644
--- a/python/python-sdk-configurator/backend/resources/intellij.python.sdkConfigurator.backend.xml
+++ b/python/python-sdk-configurator/backend/resources/intellij.python.sdkConfigurator.backend.xml
@@ -16,10 +16,6 @@
-
-
-
diff --git a/python/python-sdk-configurator/backend/src/impl/backendLib.kt b/python/python-sdk-configurator/backend/src/impl/backendLib.kt
index a395f5e66a6a..4646fb7a3c5f 100644
--- a/python/python-sdk-configurator/backend/src/impl/backendLib.kt
+++ b/python/python-sdk-configurator/backend/src/impl/backendLib.kt
@@ -30,9 +30,20 @@ import kotlinx.coroutines.withContext
private val askUserMutex = Mutex()
-// TODO: DOC
-internal fun configureSdkAskingUser(project: Project) {
+/**
+ * Same as [configureSdkAutomatically] but in a separate coroutine
+ */
+internal fun configureSdkAskingUserBg(project: Project) {
project.service().scope.launch(Dispatchers.Default) {
+ configureSdkAskingUser(project)
+ }
+}
+
+/**
+ * Ask user for list of modules and configure them
+ */
+internal suspend fun configureSdkAskingUser(project: Project) {
+ withContext(Dispatchers.Default) {
askUserMutex.withLock {
val moduleToSuggestedSdk = getModulesWithoutSDK(project)
if (moduleToSuggestedSdk.modules.isNotEmpty()) {
diff --git a/python/python-sdk-configurator/backend/src/impl/platformBridge/ConfigureSDKAction.kt b/python/python-sdk-configurator/backend/src/impl/platformBridge/ConfigureSDKAction.kt
index fc39d7effc3e..ebc8fd653827 100644
--- a/python/python-sdk-configurator/backend/src/impl/platformBridge/ConfigureSDKAction.kt
+++ b/python/python-sdk-configurator/backend/src/impl/platformBridge/ConfigureSDKAction.kt
@@ -4,6 +4,7 @@ import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
+import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUserBg
import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
internal class ConfigureSDKAction : AnAction() {
@@ -13,7 +14,7 @@ internal class ConfigureSDKAction : AnAction() {
if (!enableSDKAutoConfigurator) {
return
}
- configureSdkAskingUser(project)
+ configureSdkAskingUserBg(project)
}
override fun update(e: AnActionEvent) {
diff --git a/python/python-sdk-configurator/backend/src/impl/platformBridge/ModelRebuiltListenerImpl.kt b/python/python-sdk-configurator/backend/src/impl/platformBridge/ModelRebuiltListenerImpl.kt
index 520157dedc04..41a9fdde637f 100644
--- a/python/python-sdk-configurator/backend/src/impl/platformBridge/ModelRebuiltListenerImpl.kt
+++ b/python/python-sdk-configurator/backend/src/impl/platformBridge/ModelRebuiltListenerImpl.kt
@@ -3,9 +3,8 @@ package com.intellij.python.sdkConfigurator.backend.impl.platformBridge
import com.intellij.openapi.extensions.ExtensionNotApplicableException
import com.intellij.openapi.project.Project
import com.intellij.python.pyproject.model.api.ModelRebuiltListener
-import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
+import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUserBg
import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
-import kotlinx.coroutines.sync.Mutex
internal class ModelRebuiltListenerImpl : ModelRebuiltListener {
init {
@@ -15,7 +14,7 @@ internal class ModelRebuiltListenerImpl : ModelRebuiltListener {
}
override fun modelRebuilt(project: Project) {
- configureSdkAskingUser(project)
+ configureSdkAskingUserBg(project)
}
}
diff --git a/python/python-sdk-configurator/backend/src/impl/rpcBridge/BackendTopicListener.kt b/python/python-sdk-configurator/backend/src/impl/rpcBridge/BackendTopicListener.kt
deleted file mode 100644
index ed9bb9e76efd..000000000000
--- a/python/python-sdk-configurator/backend/src/impl/rpcBridge/BackendTopicListener.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.intellij.python.sdkConfigurator.backend.impl.rpcBridge
-
-import com.intellij.openapi.project.Project
-import com.intellij.platform.rpc.topics.ProjectRemoteTopic
-import com.intellij.platform.rpc.topics.ProjectRemoteTopicListener
-import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
-import com.intellij.python.sdkConfigurator.common.impl.DETECT_SDK_FOR_MODULES
-
-internal class BackendTopicListener : ProjectRemoteTopicListener {
- override val topic: ProjectRemoteTopic = DETECT_SDK_FOR_MODULES
-
- override fun handleEvent(project: Project, event: Unit) {
- configureSdkAskingUser(project)
- }
-}
diff --git a/python/python-sdk-configurator/backend/src/impl/rpcBridge/SdkConfiguratorApiImpl.kt b/python/python-sdk-configurator/backend/src/impl/rpcBridge/SdkConfiguratorApiImpl.kt
index 66dada0bf9c4..d5666cda6184 100644
--- a/python/python-sdk-configurator/backend/src/impl/rpcBridge/SdkConfiguratorApiImpl.kt
+++ b/python/python-sdk-configurator/backend/src/impl/rpcBridge/SdkConfiguratorApiImpl.kt
@@ -2,6 +2,7 @@ package com.intellij.python.sdkConfigurator.backend.impl.rpcBridge
import com.intellij.platform.project.ProjectId
import com.intellij.platform.project.findProject
+import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAutomatically
import com.intellij.python.sdkConfigurator.common.impl.ModuleName
import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
@@ -10,4 +11,8 @@ internal object SdkConfiguratorApiImpl : SdkConfiguratorBackEndApi {
override suspend fun configureSdkAutomatically(projectId: ProjectId, onlyModules: Set) {
configureSdkAutomatically(projectId.findProject(), onlyModules)
}
+
+ override suspend fun configureAskingUser(projectId: ProjectId) {
+ configureSdkAskingUser(projectId.findProject())
+ }
}
\ No newline at end of file
diff --git a/python/python-sdk-configurator/common/resources/intellij.python.sdkConfigurator.common.xml b/python/python-sdk-configurator/common/resources/intellij.python.sdkConfigurator.common.xml
index f7b2a6632b72..22c04e273843 100644
--- a/python/python-sdk-configurator/common/resources/intellij.python.sdkConfigurator.common.xml
+++ b/python/python-sdk-configurator/common/resources/intellij.python.sdkConfigurator.common.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/python/python-sdk-configurator/common/src/impl/SdkConfiguratorBackEndApi.kt b/python/python-sdk-configurator/common/src/impl/SdkConfiguratorBackEndApi.kt
index ed834bda66c5..cc678e90d641 100644
--- a/python/python-sdk-configurator/common/src/impl/SdkConfiguratorBackEndApi.kt
+++ b/python/python-sdk-configurator/common/src/impl/SdkConfiguratorBackEndApi.kt
@@ -1,9 +1,11 @@
package com.intellij.python.sdkConfigurator.common.impl
import com.intellij.platform.project.ProjectId
+import com.intellij.platform.rpc.RemoteApiProviderService
import com.intellij.platform.rpc.topics.ProjectRemoteTopic
import fleet.rpc.RemoteApi
import fleet.rpc.Rpc
+import fleet.rpc.remoteApiDescriptor
import kotlinx.serialization.Serializable
/**
@@ -12,9 +14,14 @@ import kotlinx.serialization.Serializable
@Rpc
interface SdkConfiguratorBackEndApi : RemoteApi {
/***
- * Configure SDK for all modules in [projectId] if their names in [onlyModules]
+ * Configure SDK for all modules in [projectId] if their names in [onlyModules] unconditionally
*/
suspend fun configureSdkAutomatically(projectId: ProjectId, onlyModules: Set)
+
+ /**
+ * Ask user about modules, then call [configureSdkAutomatically]
+ */
+ suspend fun configureAskingUser(projectId: ProjectId)
}
typealias ModuleName = String
@@ -29,4 +36,9 @@ val SHOW_SDK_CONFIG_UI_TOPIC: ProjectRemoteTopic = ProjectRemoteTopi
*/
@Serializable
data class ModulesDTO(val modules: Map) {
-}
\ No newline at end of file
+}
+
+/**
+ * [SdkConfiguratorBackEndApi] instance
+ */
+suspend fun SdkConfiguratorBackEndApi(): SdkConfiguratorBackEndApi = RemoteApiProviderService.resolve(remoteApiDescriptor())
\ No newline at end of file
diff --git a/python/python-sdk-configurator/common/src/impl/detectModulesImpl.kt b/python/python-sdk-configurator/common/src/impl/detectModulesImpl.kt
deleted file mode 100644
index f6f8a0f3b16f..000000000000
--- a/python/python-sdk-configurator/common/src/impl/detectModulesImpl.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.intellij.python.sdkConfigurator.common.impl
-
-import com.intellij.platform.rpc.topics.ProjectRemoteTopic
-import kotlinx.serialization.builtins.serializer
-
-/**
- * Backend listens for this topic to start SDK detection process
- */
-val DETECT_SDK_FOR_MODULES: ProjectRemoteTopic = ProjectRemoteTopic("PySDKConfigurationDetectSDKTopic", Unit.serializer())
-
diff --git a/python/python-sdk-configurator/common/src/publicApi.kt b/python/python-sdk-configurator/common/src/publicApi.kt
index 059d91956a12..76689c4f8acf 100644
--- a/python/python-sdk-configurator/common/src/publicApi.kt
+++ b/python/python-sdk-configurator/common/src/publicApi.kt
@@ -2,8 +2,8 @@ package com.intellij.python.sdkConfigurator.common
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.registry.Registry
-import com.intellij.platform.rpc.topics.sendToClient
-import com.intellij.python.sdkConfigurator.common.impl.DETECT_SDK_FOR_MODULES
+import com.intellij.platform.project.projectId
+import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
/**
@@ -11,14 +11,10 @@ import com.intellij.python.sdkConfigurator.common.impl.DETECT_SDK_FOR_MODULES
*/
val enableSDKAutoConfigurator: Boolean get() = Registry.`is`("intellij.python.sdkConfigurator.auto")
+
/**
- * Check if [enableSDKAutoConfigurator] (return `false` if not) and start detecting process.
- * it might ask user for list of modules and then detect them
+ * it might ask user for list of modules and then detect SDK for them
*/
-fun detectSdkForModulesIn(project: Project): Boolean {
- if (!enableSDKAutoConfigurator) {
- return false
- }
- DETECT_SDK_FOR_MODULES.sendToClient(project, Unit)
- return true
+suspend fun detectSdkForModulesIn(project: Project) {
+ SdkConfiguratorBackEndApi().configureAskingUser(project.projectId())
}
diff --git a/python/python-sdk-configurator/frontend/resources/messages/PySdkConfiguratorFrontendBundle.properties b/python/python-sdk-configurator/frontend/resources/messages/PySdkConfiguratorFrontendBundle.properties
index c9c6b99e6560..64ca45526a7e 100644
--- a/python/python-sdk-configurator/frontend/resources/messages/PySdkConfiguratorFrontendBundle.properties
+++ b/python/python-sdk-configurator/frontend/resources/messages/PySdkConfiguratorFrontendBundle.properties
@@ -1 +1,4 @@
-python.sdk.configurator.frontend.choose.modules.title=Choose Modules to Configure SDK For
\ No newline at end of file
+python.sdk.configurator.frontend.choose.modules.title=Configure Modules Environment
+python.sdk.configurator.frontend.choose.modules.text=Pick the ones you want to use to run code and set up environment for them
+python.sdk.configurator.frontend.choose.modules.project.structure=Project Structure
+python.sdk.configurator.frontend.choose.modules.environment=Environment
diff --git a/python/python-sdk-configurator/frontend/src/components/ModuleList.kt b/python/python-sdk-configurator/frontend/src/components/ModuleList.kt
index ac261354a404..d1a0a68320cd 100644
--- a/python/python-sdk-configurator/frontend/src/components/ModuleList.kt
+++ b/python/python-sdk-configurator/frontend/src/components/ModuleList.kt
@@ -1,17 +1,18 @@
package com.intellij.python.sdkConfigurator.frontend.components
-import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableIntState
-import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateSet
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.intellij.python.sdkConfigurator.frontend.ModuleInfo
import kotlinx.collections.immutable.ImmutableMap
-import org.jetbrains.jewel.ui.component.Checkbox
+import org.jetbrains.annotations.Nls
+import org.jetbrains.jewel.foundation.theme.JewelTheme
+import org.jetbrains.jewel.ui.component.CheckboxRow
import org.jetbrains.jewel.ui.component.Text
import org.jetbrains.jewel.ui.component.VerticallyScrollableContainer
@@ -21,23 +22,42 @@ internal fun ModuleList(
moduleItems: ImmutableMap,
checked: SnapshotStateSet,
onCheckChange: (String, Boolean) -> Unit,
+ topLabel: @Nls String,
+ projectStructureLabel: @Nls String,
+ environmentLabel: @Nls String,
) {
- VerticallyScrollableContainer {
- Column(Modifier.width(500.dp)) {
- for ((moduleName, moduleInfo) in moduleItems) {
- val (parent, pythons) = moduleInfo
- Row(Modifier.padding(2.dp), verticalAlignment = Alignment.CenterVertically) {
- val checked = moduleName in checked
- val elementToChange = parent ?: moduleName
- Checkbox(
- checked = checked,
- onCheckedChange = {
- onCheckChange(elementToChange, it)
- },
- )
- Text(moduleName, Modifier.padding(start = 1.dp).clickable(true, onClick = { onCheckChange(elementToChange, !checked) }))
- Spacer(Modifier.weight(1f))
- PythonsDropDown(pythons, Modifier.width(200.dp))
+ val ts = JewelTheme.defaultTextStyle
+ val padding = 2.dp
+ val longestItemChars = remember { (listOf(projectStructureLabel) + moduleItems.keys).maxBy { it.length } }
+ val leftColumnMinSize = measureText(longestItemChars, ts)
+ val spaceBetweenCols = 16.dp
+ Column(Modifier.padding(padding), verticalArrangement = Arrangement.spacedBy(padding)) {
+ Text(topLabel, Modifier.padding(bottom = 10.dp))
+ Row(Modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween) {
+ Text(projectStructureLabel, Modifier.width(leftColumnMinSize + spaceBetweenCols + padding + 26.dp)) //~ checkbox size
+ Text(environmentLabel, textAlign = TextAlign.End)
+ }
+ val moduleItems = remember { moduleItems.entries.sortedBy { it.key } }
+ VerticallyScrollableContainer {
+ Column(Modifier, horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(padding)) {
+ for ((moduleName, moduleInfo) in moduleItems) {
+ val (parent, pythons) = moduleInfo
+ Row(Modifier.padding(padding), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(spaceBetweenCols)) {
+ val checked = moduleName in checked
+ val elementToChange = parent ?: moduleName // TODO: move logic out of UI
+ CheckboxRow(
+ moduleName,
+ checked = checked,
+ onCheckedChange = {
+ onCheckChange(elementToChange, it)
+ },
+ textStyle = ts,
+ textModifier = Modifier.width(leftColumnMinSize)
+ )
+ if (parent == null) {
+ PythonsDropDown(pythons)
+ }
+ }
}
}
}
diff --git a/python/python-sdk-configurator/frontend/src/components/PythonsDropDown.kt b/python/python-sdk-configurator/frontend/src/components/PythonsDropDown.kt
index 007e7f491d93..a499bf0951d2 100644
--- a/python/python-sdk-configurator/frontend/src/components/PythonsDropDown.kt
+++ b/python/python-sdk-configurator/frontend/src/components/PythonsDropDown.kt
@@ -1,13 +1,40 @@
package com.intellij.python.sdkConfigurator.frontend.components
+import androidx.compose.foundation.layout.widthIn
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.unit.dp
import kotlinx.collections.immutable.ImmutableList
import org.jetbrains.jewel.foundation.ExperimentalJewelApi
+import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.ui.component.ListComboBox
+import org.jetbrains.jewel.ui.component.SimpleListItem
+import org.jetbrains.jewel.ui.icons.AllIconsKeys.Language.Python
+@OptIn(ExperimentalJewelApi::class)
@Composable
-internal fun PythonsDropDown(pythons: ImmutableList, modifier: Modifier = Modifier) {
+internal fun PythonsDropDown(pythons: ImmutableList, grayedOut: Boolean = false, modifier: Modifier = Modifier) {
+ val ts = JewelTheme.defaultTextStyle
+ val longestPython = remember { pythons.maxBy { it.length } }
+ val padding = 100.dp
+ val width = measureText(longestPython, ts) + padding // Padding
var i by remember { mutableIntStateOf(0) }
- ListComboBox(pythons, i, { i = it }, modifier)
+ ListComboBox(
+ items = pythons,
+ selectedIndex = i,
+ modifier = modifier.widthIn(min = width, max = width + padding),
+ onSelectedItemChange = { i = it },
+ itemKeys = { index, _ -> index },
+ itemContent = { item, isSelected, isActive ->
+ SimpleListItem(
+ text = item,
+ selected = isSelected,
+ active = isActive,
+ icon = Python,
+ colorFilter = if (grayedOut) ColorFilter.tint(Color.Gray) else null,
+ )
+ },
+ )
}
\ No newline at end of file
diff --git a/python/python-sdk-configurator/frontend/src/components/tools.kt b/python/python-sdk-configurator/frontend/src/components/tools.kt
new file mode 100644
index 000000000000..0a65e1c4fc5e
--- /dev/null
+++ b/python/python-sdk-configurator/frontend/src/components/tools.kt
@@ -0,0 +1,15 @@
+package com.intellij.python.sdkConfigurator.frontend.components
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.rememberTextMeasurer
+import androidx.compose.ui.unit.Dp
+
+@Composable
+internal fun measureText(text: String, textStyle: TextStyle): Dp {
+ val textMeasurer = rememberTextMeasurer()
+ return with(LocalDensity.current) {
+ textMeasurer.measure(text, textStyle).size.width.toDp()
+ }
+}
\ No newline at end of file
diff --git a/python/python-sdk-configurator/frontend/src/package-info.java b/python/python-sdk-configurator/frontend/src/package-info.java
index 73502c3f5af2..19baa5e9a068 100644
--- a/python/python-sdk-configurator/frontend/src/package-info.java
+++ b/python/python-sdk-configurator/frontend/src/package-info.java
@@ -1,3 +1,6 @@
+/**
+ * Front-end implementation, do not access directly
+ */
@ApiStatus.Internal
package com.intellij.python.sdkConfigurator.frontend;
diff --git a/python/python-sdk-configurator/frontend/src/rpcBridge/FrontendTopicListener.kt b/python/python-sdk-configurator/frontend/src/rpcBridge/FrontendTopicListener.kt
index 1c3746efe4d2..7bebcced34cc 100644
--- a/python/python-sdk-configurator/frontend/src/rpcBridge/FrontendTopicListener.kt
+++ b/python/python-sdk-configurator/frontend/src/rpcBridge/FrontendTopicListener.kt
@@ -9,6 +9,7 @@ import com.intellij.platform.rpc.topics.ProjectRemoteTopic
import com.intellij.platform.rpc.topics.ProjectRemoteTopicListener
import com.intellij.python.sdkConfigurator.common.impl.ModulesDTO
import com.intellij.python.sdkConfigurator.common.impl.SHOW_SDK_CONFIG_UI_TOPIC
+import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
import com.intellij.python.sdkConfigurator.frontend.askUser
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -22,7 +23,7 @@ internal class FrontendTopicListener : ProjectRemoteTopicListener {
// Ask user to choose modules, then ask backend to configure it
askUser(project, event) { modulesChosenByUser ->
scope.launch {
- getBackendApi().configureSdkAutomatically(project.projectId(), modulesChosenByUser)
+ SdkConfiguratorBackEndApi().configureSdkAutomatically(project.projectId(), modulesChosenByUser)
}
}
}
diff --git a/python/python-sdk-configurator/frontend/src/rpcBridge/apiObtainer.kt b/python/python-sdk-configurator/frontend/src/rpcBridge/apiObtainer.kt
deleted file mode 100644
index 491afe7a8e3a..000000000000
--- a/python/python-sdk-configurator/frontend/src/rpcBridge/apiObtainer.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.intellij.python.sdkConfigurator.frontend.rpcBridge
-
-import com.intellij.platform.rpc.RemoteApiProviderService
-import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
-import fleet.rpc.remoteApiDescriptor
-
-
-internal suspend fun getBackendApi() = RemoteApiProviderService.resolve(remoteApiDescriptor())
-
diff --git a/python/python-sdk-configurator/frontend/src/swingBridge.kt b/python/python-sdk-configurator/frontend/src/swingBridge.kt
index dd2952f78fde..1dffc18e2ba9 100644
--- a/python/python-sdk-configurator/frontend/src/swingBridge.kt
+++ b/python/python-sdk-configurator/frontend/src/swingBridge.kt
@@ -5,6 +5,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.python.sdkConfigurator.common.impl.ModuleName
import com.intellij.python.sdkConfigurator.common.impl.ModulesDTO
+import com.intellij.python.sdkConfigurator.frontend.PySdkConfiguratorFrontendBundle.message
import com.intellij.python.sdkConfigurator.frontend.components.ModuleList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -28,7 +29,8 @@ internal suspend fun askUser(project: Project, modules: ModulesDTO, onResult: (S
private class MyDialog(project: Project, private val viewModel: ModulesViewModel) : DialogWrapper(project) {
init {
- title = PySdkConfiguratorFrontendBundle.message("python.sdk.configurator.frontend.choose.modules.title")
+ title = message("python.sdk.configurator.frontend.choose.modules.title")
+ isResizable = false
init()
}
@@ -36,7 +38,10 @@ private class MyDialog(project: Project, private val viewModel: ModulesViewModel
override fun createCenterPanel(): JComponent {
enableNewSwingCompositing()
return compose(focusOnClickInside = true, content = {
- ModuleList(viewModel.checkBoxItems, viewModel.checked, viewModel::clicked)
+ ModuleList(viewModel.checkBoxItems, viewModel.checked, viewModel::clicked,
+ topLabel = message("python.sdk.configurator.frontend.choose.modules.text"),
+ projectStructureLabel = message("python.sdk.configurator.frontend.choose.modules.project.structure"),
+ environmentLabel = message("python.sdk.configurator.frontend.choose.modules.environment"))
})
}
}
\ No newline at end of file
diff --git a/python/src/com/jetbrains/python/inspections/PyInterpreterInspection.java b/python/src/com/jetbrains/python/inspections/PyInterpreterInspection.java
index b0766eaaf1b5..38ad254f80e2 100644
--- a/python/src/com/jetbrains/python/inspections/PyInterpreterInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyInterpreterInspection.java
@@ -58,7 +58,7 @@ import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import static com.intellij.python.sdkConfigurator.common.PublicApiKt.detectSdkForModulesIn;
+import static com.jetbrains.python.inspections.PyInterpreterInspectionExKt.detectSdkForModulesForJvmIn;
import static com.jetbrains.python.inspections.PyInterpreterInspectionExKt.findAllSortedForModuleForJvm;
@@ -343,7 +343,7 @@ public final class PyInterpreterInspection extends PyInspection {
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
- if (!detectSdkForModulesIn(project)) {
+ if (!detectSdkForModulesForJvmIn(project)) {
PyProjectSdkConfiguration.INSTANCE.configureSdkUsingCreateSdkInfo(myModule, myCreateSdkInfo);
}
}
diff --git a/python/src/com/jetbrains/python/inspections/PyInterpreterInspectionEx.kt b/python/src/com/jetbrains/python/inspections/PyInterpreterInspectionEx.kt
index 5c7b1ab208b9..b3bc445a5a82 100644
--- a/python/src/com/jetbrains/python/inspections/PyInterpreterInspectionEx.kt
+++ b/python/src/com/jetbrains/python/inspections/PyInterpreterInspectionEx.kt
@@ -1,13 +1,37 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.inspections
+import com.intellij.openapi.components.Service
+import com.intellij.openapi.components.service
import com.intellij.openapi.module.Module
import com.intellij.openapi.progress.runBlockingMaybeCancellable
+import com.intellij.openapi.project.Project
+import com.intellij.python.sdkConfigurator.common.detectSdkForModulesIn
+import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.jetbrains.python.sdk.configuration.CreateSdkInfo
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
import org.jetbrains.annotations.ApiStatus
+/**
+ * To be used by [PyInterpreterInspection] only
+ */
+@ApiStatus.Internal
+internal fun detectSdkForModulesForJvmIn(project: Project): Boolean {
+ if (!enableSDKAutoConfigurator) {
+ return false
+ }
+ project.service().scope.launch {
+ detectSdkForModulesIn(project)
+ }
+ return true
+}
+
+@Service(Service.Level.PROJECT)
+private class MyService(val scope: CoroutineScope)
+
/**
* To be used by [PyInterpreterInspection] only
*/