From d8edf9e902441c49e9617592acc1bcb382a4e658 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Mon, 23 Sep 2024 19:05:40 +0200 Subject: [PATCH] Python remove redundant classes GitOrigin-RevId: 05a6480b47113f21416c46db043ab88581202ba6 --- .../PythonInterpreterDetailsConfigurable.kt | 3 - .../configuration/PythonSdkDetailsDialog.java | 472 ------------------ 2 files changed, 475 deletions(-) delete mode 100644 python/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java diff --git a/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurable.kt b/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurable.kt index 54d9895b3540..1abd0abd24d8 100644 --- a/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurable.kt +++ b/python/src/com/jetbrains/python/configuration/PythonInterpreterDetailsConfigurable.kt @@ -26,9 +26,6 @@ class PythonInterpreterDetailsConfigurable(project: Project, override fun isModified(): Boolean = initialSdkName != currentSdkName || underlyingConfigurable.isModified - /** - * TODO Shouldn't be here the association updated (see [com.jetbrains.python.configuration.PythonSdkDetailsDialog.editSdk]). - */ override fun apply() { underlyingConfigurable.apply() diff --git a/python/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java b/python/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java deleted file mode 100644 index 4f7b6fbd138c..000000000000 --- a/python/src/com/jetbrains/python/configuration/PythonSdkDetailsDialog.java +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.jetbrains.python.configuration; - -import com.google.common.collect.Sets; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.actionSystem.ActionUpdateThread; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.project.DumbAwareAction; -import com.intellij.openapi.project.DumbAwareToggleAction; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.SdkModel; -import com.intellij.openapi.projectRoots.SdkModificator; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.util.Disposer; -import com.intellij.remote.RemoteSdkAdditionalData; -import com.intellij.ui.*; -import com.intellij.ui.components.JBList; -import com.intellij.util.NullableConsumer; -import com.jetbrains.python.PyBundle; -import com.jetbrains.python.packaging.PyPackageManagers; -import com.jetbrains.python.remote.PythonRemoteInterpreterManager; -import com.jetbrains.python.sdk.*; -import com.jetbrains.python.sdk.add.PyAddSdkDialog; -import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; -import one.util.streamex.StreamEx; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import javax.swing.event.ListSelectionListener; -import java.awt.*; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.Consumer; - -public class PythonSdkDetailsDialog extends DialogWrapper { - private static final Logger LOG = Logger.getInstance(PythonSdkDetailsDialog.class); - - private boolean myModified = false; - - private final @NotNull Project myProject; - - private final @Nullable Module myModule; - - private final @NotNull NullableConsumer mySelectedSdkCallback; - - private final @NotNull Consumer myCancelCallback; - - private final @NotNull SdkModel.Listener mySdkModelListener; - - private final @NotNull PyConfigurableInterpreterList myInterpreterList; - - private final @NotNull ProjectSdksModel myProjectSdksModel; - - private final @NotNull JBList mySdkList; - - private final @NotNull JPanel myMainPanel; - - private boolean myHideOtherProjectVirtualenvs = false; - - public PythonSdkDetailsDialog(@NotNull Project project, - @Nullable Module module, - @NotNull NullableConsumer selectedSdkCallback, - @NotNull Consumer cancelCallback) { - super(project); - setTitle(PyBundle.message("sdk.details.dialog.title")); - - myProject = project; - myModule = module; - mySelectedSdkCallback = selectedSdkCallback; - myCancelCallback = cancelCallback; - - // there is an assumption that dialog started with unmodified sdks model - // otherwise processing `Cancel` will be more complicated - // to correctly revert changes - mySdkModelListener = new MySdkModelListener(); - myInterpreterList = PyConfigurableInterpreterList.getInstance(myProject); - myProjectSdksModel = myInterpreterList.getModel(); - myProjectSdksModel.addListener(mySdkModelListener); - - mySdkList = buildSdkList(e -> updateOkButton()); - myMainPanel = buildPanel( - mySdkList, - new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - addSdk(); - updateOkButton(); - } - }, - new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - editSdk(); - updateOkButton(); - } - }, - new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - removeSdk(); - updateOkButton(); - } - }, - new ToggleVirtualEnvFilterButton(), - new ShowPathButton() - ); - - init(); - refreshSdkList(); - updateOkButton(); - } - - @Override - protected void dispose() { - myProjectSdksModel.removeListener(mySdkModelListener); - super.dispose(); - } - - private static @NotNull JBList buildSdkList(@NotNull ListSelectionListener selectionListener) { - final JBList result = new JBList<>(); - result.setCellRenderer(new PySdkListCellRenderer()); - result.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - result.addListSelectionListener(selectionListener); - ListSpeedSearch.installOn(result); - return result; - } - - private static @NotNull JPanel buildPanel(@NotNull JBList sdkList, - @NotNull AnActionButtonRunnable addAction, - @NotNull AnActionButtonRunnable editAction, - @NotNull AnActionButtonRunnable removeAction, - AnAction @NotNull ... extraActions) { - return ToolbarDecorator.createDecorator(sdkList) - .disableUpDownActions() - .setAddAction(addAction) - .setEditAction(editAction) - .setRemoveAction(removeAction) - .addExtraActions(extraActions) - .setPreferredSize(new Dimension(600, 500)) - .createPanel(); - } - - @Override - protected @Nullable JComponent createCenterPanel() { - return myMainPanel; - } - - @Override - public @Nullable JComponent getPreferredFocusedComponent() { - return mySdkList; - } - - private void updateOkButton() { - super.setOKActionEnabled(myModified || myProjectSdksModel.isModified() || isAnotherSdkSelected()); - } - - /** - * Checks whether the selection has changed from the initial one. - *

- * Note that multiple selection is ambiguous to treat it as the indication for the current project interpreter. - * - * @return {@code true} if the selection has changed and {@code false} otherwise - */ - private boolean isAnotherSdkSelected() { - if (mySdkList.getSelectedValuesList().size() > 1) { - return false; - } - Sdk originalSelectedSdk = getOriginalSelectedSdk(); - return originalSelectedSdk != null && originalSelectedSdk != getSdk(); - } - - @Override - protected void doOKAction() { - apply(); - super.doOKAction(); - } - - @Override - public void doCancelAction() { - final boolean modified = myModified || myProjectSdksModel.isModified(); - if (modified) { - myProjectSdksModel.reset(myProject); - } - myModified = false; - myCancelCallback.accept(modified); - super.doCancelAction(); - } - - private void apply() { - try { - myProjectSdksModel.apply(); - } - catch (ConfigurationException e) { - LOG.error(e); - } - myModified = false; - final Sdk sdk = getOriginalSelectedSdk(); - mySelectedSdkCallback.consume(sdk); - if (sdk != null) { - PyPackageManagers.getInstance().clearCache(sdk); - } - Disposer.dispose(getDisposable()); - } - - private @Nullable Sdk getOriginalSelectedSdk() { - final Sdk editableSdk = getEditableSelectedSdk(); - return editableSdk == null ? null : myProjectSdksModel.findSdk(editableSdk); - } - - private @Nullable Sdk getEditableSelectedSdk() { - return getTheOnlyItemOrNull(mySdkList.getSelectedValuesList()); - } - - private static @Nullable T getTheOnlyItemOrNull(@NotNull List collection) { - if (collection.size() == 1) { - return collection.get(0); - } - else { - return null; - } - } - - private void refreshSdkList() { - final List allPythonSdks = myInterpreterList.getAllPythonSdks(myProject, myModule); - Sdk projectSdk = getSdk(); - final List notAssociatedWithOtherProjects = StreamEx - .of(allPythonSdks) - .filter(sdk -> !PySdkExtKt.isAssociatedWithAnotherModule(sdk, myModule)) - .toList(); - - final List pythonSdks = myHideOtherProjectVirtualenvs ? notAssociatedWithOtherProjects : allPythonSdks; - mySdkList.setModel(new CollectionListModel<>(pythonSdks)); - - if (projectSdk != null) { - projectSdk = myProjectSdksModel.findSdk(projectSdk.getName()); - mySdkList.clearSelection(); - mySdkList.setSelectedValue(projectSdk, true); - mySdkList.updateUI(); - } - } - - private @Nullable Sdk getSdk() { - if (myModule == null) { - return ProjectRootManager.getInstance(myProject).getProjectSdk(); - } - final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule); - return rootManager.getSdk(); - } - - private void addSdk() { - PyAddSdkDialog.show(myProject, myModule, Arrays.asList(myProjectSdksModel.getSdks()), new SdkAddedCallback()); - } - - private void setSelectedSdk(@Nullable Sdk selectedSdk) { - mySdkList.setSelectedValue(selectedSdk == null ? null : myProjectSdksModel.findSdk(selectedSdk.getName()), true); - } - - private void editSdk() { - final Sdk currentSdk = getEditableSelectedSdk(); - if (currentSdk != null) { - if (currentSdk.getSdkAdditionalData() instanceof RemoteSdkAdditionalData) { - editRemoteSdk(currentSdk); - } - else { - editSdk(currentSdk); - } - } - } - - private void editRemoteSdk(Sdk currentSdk) { - PythonRemoteInterpreterManager remoteInterpreterManager = PythonRemoteInterpreterManager.getInstance(); - if (remoteInterpreterManager != null) { - final SdkModificator modificator = currentSdk.getSdkModificator(); - Set existingSdks = Sets.newHashSet(myProjectSdksModel.getSdks()); - existingSdks.remove(currentSdk); - if (remoteInterpreterManager.editSdk(myProject, modificator, existingSdks)) { - commitAndRefresh(modificator); - } - } - } - - private void editSdk(final Sdk currentSdk) { - final SdkModificator modificator = currentSdk.getSdkModificator(); - final EditSdkDialog dialog = new EditSdkDialog(myProject, modificator, s -> { - if (isDuplicateSdkName(s, currentSdk)) { - return PyBundle.message("sdk.details.dialog.error.duplicate.name"); - } - return null; - }); - if (dialog.showAndGet()) { - final boolean pathChanged = !Objects.equals(currentSdk.getHomePath(), dialog.getHomePath()); - if (!modificator.getName().equals(dialog.getName()) || pathChanged || dialog.isAssociateChanged()) { - modificator.setName(dialog.getName()); - modificator.setHomePath(dialog.getHomePath()); - - if (dialog.isAssociateChanged()) { - setSdkAssociated(modificator, dialog.associateWithProject()); - } - commitAndRefresh(modificator); - if (pathChanged) { - reloadSdk(currentSdk); - } - } - } - } - - private void setSdkAssociated(SdkModificator modificator, boolean isAssociated) { - PythonSdkAdditionalData additionalData = (PythonSdkAdditionalData)modificator.getSdkAdditionalData(); - if (additionalData == null) { - additionalData = new PythonSdkAdditionalData(PythonSdkFlavor.getFlavor(modificator.getHomePath())); - modificator.setSdkAdditionalData(additionalData); - } - if (isAssociated && myModule != null) { - additionalData.associateWithModule(myModule); - } - else if (isAssociated) { - additionalData.setAssociatedModulePath(myProject.getBasePath()); - } - else { - additionalData.resetAssociatedModulePath(); - } - } - - private boolean isDuplicateSdkName(String s, Sdk sdk) { - for (Sdk existingSdk : myProjectSdksModel.getSdks()) { - if (existingSdk == sdk) { - continue; - } - if (existingSdk.getName().equals(s)) { - return true; - } - } - return false; - } - - private void removeSdk() { - final List selectedSdks = mySdkList.getSelectedValuesList(); - if (!selectedSdks.isEmpty()) { - selectedSdks.forEach(selectedSdk -> myProjectSdksModel.removeSdk(selectedSdk)); - refreshSdkList(); - final Sdk currentSdk = getSdk(); - if (currentSdk != null) { - mySdkList.setSelectedValue(currentSdk, true); - } - } - } - - private void reloadSdk() { - final Sdk currentSdk = getEditableSelectedSdk(); - if (currentSdk != null) { - reloadSdk(currentSdk); - } - } - - private void reloadSdk(@NotNull Sdk currentSdk) { - PythonSdkUpdater.updateVersionAndPathsSynchronouslyAndScheduleRemaining(currentSdk, myProject); - } - - private void commitAndRefresh(@NotNull SdkModificator modificator) { - modificator.commitChanges(); - myModified = true; - refreshSdkList(); - } - - private class ToggleVirtualEnvFilterButton extends DumbAwareToggleAction { - ToggleVirtualEnvFilterButton() { - super(PyBundle.messagePointer("sdk.details.dialog.hide.all.virtual.envs"), Presentation.NULL_STRING, AllIcons.General.Filter); - } - - @Override - public boolean isSelected(AnActionEvent e) { - return myHideOtherProjectVirtualenvs; - } - - @Override - public void setSelected(AnActionEvent e, boolean state) { - myHideOtherProjectVirtualenvs = state; - refreshSdkList(); - updateOkButton(); - } - - @Override - public @NotNull ActionUpdateThread getActionUpdateThread() { - return ActionUpdateThread.EDT; - } - } - - private class ShowPathButton extends DumbAwareAction { - ShowPathButton() { - super(PyBundle.messagePointer("sdk.details.dialog.show.interpreter.paths"), AllIcons.Actions.ShowAsTree); - } - - @Override - public void update(@NotNull AnActionEvent e) { - e.getPresentation().setEnabled(getEditableSelectedSdk() != null); - } - - @Override - public void actionPerformed(@NotNull AnActionEvent e) { - Sdk sdk = getEditableSelectedSdk(); - if (sdk == null) return; - final PythonPathEditor pathEditor = createPathEditor(sdk); - final SdkModificator sdkModificator = sdk.getSdkModificator(); - - PythonPathDialog dialog = new PythonPathDialog(myProject, pathEditor); - pathEditor.reset(sdkModificator); - if (dialog.showAndGet()) { - if (pathEditor.isModified()) { - pathEditor.apply(sdkModificator); - commitAndRefresh(sdkModificator); - reloadSdk(sdk); - } - } - updateOkButton(); - } - - @Override - public @NotNull ActionUpdateThread getActionUpdateThread() { - return ActionUpdateThread.EDT; - } - } - - private @NotNull PythonPathEditor createPathEditor(final @NotNull Sdk sdk) { - PythonPathEditor pathEditor; - if (PythonSdkUtil.isRemote(sdk)) { - pathEditor = new PyRemotePathEditor(myProject, sdk); - } - else { - pathEditor = new PythonPathEditor(PyBundle.message("python.sdk.configuration.tab.title"), OrderRootType.CLASSES, - FileChooserDescriptorFactory.createAllButJarContentsDescriptor()); - } - pathEditor.addReloadPathsActionCallback(this::reloadSdk); - return pathEditor; - } - - private class MySdkModelListener implements SdkModel.Listener { - - @Override - public void sdkAdded(@NotNull Sdk sdk) { - refreshSdkList(); - } - - @Override - public void sdkChanged(@NotNull Sdk sdk, String previousName) { - refreshSdkList(); - } - } - - private class SdkAddedCallback implements Consumer { - @Override - public void accept(@Nullable Sdk sdk) { - if (sdk != null && myProjectSdksModel.findSdk(sdk.getName()) == null) { - myProjectSdksModel.addSdk(sdk); - setSelectedSdk(sdk); - } - } - } -}