diff --git a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyContentEntriesModuleConfigurable.kt b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyContentEntriesModuleConfigurable.kt index c25753f96113..57a45fbd839c 100644 --- a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyContentEntriesModuleConfigurable.kt +++ b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyContentEntriesModuleConfigurable.kt @@ -24,10 +24,7 @@ internal class PyContentEntriesModuleConfigurable(private val module: Module) : private var modifiableModel: ModifiableRootModel? = null private var editor: PyContentEntriesEditor? = null private val isPyProjectTomlManaged: Boolean - get() { - val pending = module.project.getUserData(PythonContentEntriesConfigurable.PYPROJECT_TOML_PENDING_KEY) - return pending ?: PyProjectModelSettings.getInstance(module.project).usePyprojectToml - } + get() = PyProjectModelSettings.getInstance(module.project).usePyprojectToml override fun getDisplayName(): String = PyBundle.message("configurable.PyContentEntriesModuleConfigurable.display.name") diff --git a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyModuleDependenciesConfigurable.java b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyModuleDependenciesConfigurable.java index f634e59f6b80..de6c924429c7 100644 --- a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyModuleDependenciesConfigurable.java +++ b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PyModuleDependenciesConfigurable.java @@ -10,7 +10,7 @@ import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleOrderEntry; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderEntry; -import com.intellij.python.pyproject.model.PyProjectModelSettings; +import com.intellij.python.pyproject.model.api.PyProjectTomlAPIKt; import com.intellij.ui.AncestorListenerAdapter; import com.intellij.ui.CheckBoxList; import com.intellij.ui.ToolbarDecorator; @@ -30,10 +30,13 @@ import javax.swing.event.AncestorEvent; import java.awt.BorderLayout; import java.awt.Insets; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.ResourceBundle; +import java.util.Set; + public class PyModuleDependenciesConfigurable implements UnnamedConfigurable { @@ -41,7 +44,7 @@ public class PyModuleDependenciesConfigurable implements UnnamedConfigurable { private List myInitialDependencies; private final JPanel myMainPanel; private final JPanel myListHolderPanel; - private final CheckBoxList myDependenciesList; + private final CheckBoxList myDependenciesList = new CheckBoxList<>(); private final JBLabel myTitleLabel; public PyModuleDependenciesConfigurable(Module module) { @@ -65,7 +68,6 @@ public class PyModuleDependenciesConfigurable implements UnnamedConfigurable { GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); } - myDependenciesList = new CheckBoxList<>(); resetModel(); ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myDependenciesList, new EditableListModelDecorator( @@ -81,9 +83,12 @@ public class PyModuleDependenciesConfigurable implements UnnamedConfigurable { }); } + private boolean isPyProjectTomlManaged() { + return PyProjectTomlAPIKt.isPyProjectTomlBased(myModule); + } + private void updateEnabledState() { - Boolean pending = myModule.getProject().getUserData(PythonContentEntriesConfigurable.PYPROJECT_TOML_PENDING_KEY); - boolean managed = pending != null ? pending : PyProjectModelSettings.getInstance(myModule.getProject()).getUsePyprojectToml(); + boolean managed = isPyProjectTomlManaged(); myDependenciesList.setEnabled(!managed); if (managed) { myTitleLabel.setText(PyBundle.message("python.pyproject.toml.dependencies.managed.hint")); @@ -143,18 +148,15 @@ public class PyModuleDependenciesConfigurable implements UnnamedConfigurable { public JComponent $$$getRootComponent$$$() { return myMainPanel; } private void resetModel() { - myInitialDependencies = Arrays.asList(ModuleRootManager.getInstance(myModule).getDependencies()); - List possibleDependencies = new ArrayList<>(myInitialDependencies); - for (Module otherModule : ModuleManager.getInstance(myModule.getProject()).getModules()) { - if (!possibleDependencies.contains(otherModule) && otherModule != myModule) { - possibleDependencies.add(otherModule); - } - } - myDependenciesList.setItems(possibleDependencies, module -> module.getName()); - myDependenciesList.setBorder(null); - for (Module dependency : myInitialDependencies) { - myDependenciesList.setItemSelected(dependency, true); - } + List otherModules = Arrays.stream(ModuleManager.getInstance(myModule.getProject()).getModules()) + .filter(m -> m != myModule) + .sorted(Comparator.comparing(Module::getName, String.CASE_INSENSITIVE_ORDER)) + .toList(); + + Set dependencies = Set.of(ModuleRootManager.getInstance(myModule).getDependencies()); + myDependenciesList.clear(); + otherModules.forEach(m -> myDependenciesList.addItem(m, m.getName(), dependencies.contains(m))); + myInitialDependencies = myDependenciesList.getCheckedItems(); } @Override @@ -164,38 +166,24 @@ public class PyModuleDependenciesConfigurable implements UnnamedConfigurable { @Override public boolean isModified() { - return !collectDependencies().equals(myInitialDependencies); - } - - private List collectDependencies() { - List result = new ArrayList<>(); - for (int i = 0; i < myDependenciesList.getItemsCount(); i++) { - Module module = myDependenciesList.getItemAt(i); - if (myDependenciesList.isItemSelected(module)) { - result.add(module); - } - } - return result; + return !isPyProjectTomlManaged() && !myDependenciesList.getCheckedItems().equals(myInitialDependencies); } @Override public void apply() throws ConfigurationException { + List dependencies = myDependenciesList.getCheckedItems(); + Set desired = new HashSet<>(dependencies); ApplicationManager.getApplication().runWriteAction(() -> { ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel(); - List entries = new ArrayList<>(); for (OrderEntry entry : model.getOrderEntries()) { - if (entry instanceof ModuleOrderEntry) { - entries.add((ModuleOrderEntry)entry); + if (entry instanceof ModuleOrderEntry moe && !desired.remove(moe.getModule())) { + model.removeOrderEntry(entry); } } - for (ModuleOrderEntry entry : entries) { - model.removeOrderEntry(entry); - } - for (Module module : collectDependencies()) { - model.addModuleOrderEntry(module); - } + desired.forEach(model::addModuleOrderEntry); model.commit(); }); + myInitialDependencies = dependencies; } @Override diff --git a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PythonContentEntriesConfigurable.kt b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PythonContentEntriesConfigurable.kt index f6b0ec695aa7..55d443b3aa90 100644 --- a/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PythonContentEntriesConfigurable.kt +++ b/python/ide/impl/src/com/intellij/pycharm/community/ide/impl/configuration/PythonContentEntriesConfigurable.kt @@ -7,7 +7,6 @@ import com.intellij.openapi.options.Configurable import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ui.configuration.PlatformContentEntriesConfigurable import com.intellij.openapi.ui.DialogPanel -import com.intellij.openapi.util.Key import com.intellij.python.pyproject.model.PyProjectModelSettings import com.intellij.python.pyproject.model.PyProjectModelSettings.FeatureState.ASK import com.intellij.python.pyproject.model.PyProjectModelSettings.FeatureState.OFF @@ -28,11 +27,6 @@ class PythonContentEntriesConfigurable(project: Project) : ModuleAwareProjectCon private var pyprojectPanel: DialogPanel? = null - companion object { - @JvmField - val PYPROJECT_TOML_PENDING_KEY: Key = Key.create("PythonContentEntriesConfigurable.pendingUsePyprojectToml") - } - override fun createModuleConfigurable(module: Module): Configurable { if (PlatformUtils.isPyCharmCommunity()) { return PlatformContentEntriesConfigurable(module, JavaSourceRootType.SOURCE) @@ -53,11 +47,8 @@ class PythonContentEntriesConfigurable(project: Project) : ModuleAwareProjectCon row { checkBox(PyBundle.message("python.pyproject.toml.based.project.model")) .bindSelected(settings::usePyprojectToml) - .applyToComponent { - addActionListener { project.putUserData(PYPROJECT_TOML_PENDING_KEY, isSelected) } - } .contextHelp(PyBundle.message("python.pyproject.toml.based.project.model.comment")) - } + }.bottomGap(com.intellij.ui.dsl.builder.BottomGap.SMALL) super.createComponent()?.let { parentComponent -> row { cell(parentComponent).align(Align.FILL) @@ -74,18 +65,15 @@ class PythonContentEntriesConfigurable(project: Project) : ModuleAwareProjectCon override fun apply() { pyprojectPanel?.apply() - project.putUserData(PYPROJECT_TOML_PENDING_KEY, null) super.apply() } override fun reset() { pyprojectPanel?.reset() - project.putUserData(PYPROJECT_TOML_PENDING_KEY, null) super.reset() } override fun disposeUIResources() { - project.putUserData(PYPROJECT_TOML_PENDING_KEY, null) pyprojectPanel = null super.disposeUIResources() }