From 50cff98a874393e63287c4e67f92365f891e7b67 Mon Sep 17 00:00:00 2001 From: Sergei Tachenov Date: Tue, 31 Oct 2023 15:29:40 +0200 Subject: [PATCH] IDEA-333308 Disable multi-selection in the Project and Packages Views For many projects, for example Gradle ones, it causes a lot of external library nodes to be expanded just to select multiple occurrences of a library class. This is weird UX and causes performance issues. Since multi-selection was added on purpose, it may be that some specific project view panes may actually need that. So keep the default behavior in AbstractProjectViewPaneWithAsyncSupport, but override it for the Project and Packages views. GitOrigin-RevId: c82438a6cc36b5a028210aa40a571636bb56e889 --- .../ide/projectView/impl/PackageViewPane.java | 5 +++++ .../AbstractProjectViewPaneWithAsyncSupport.java | 5 +++++ .../projectView/impl/AsyncProjectViewSupport.java | 12 ++++++++++-- .../ide/projectView/impl/ProjectViewPane.java | 5 +++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java index b31458e6a83d..53e1f4aff428 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/PackageViewPane.java @@ -53,6 +53,11 @@ public class PackageViewPane extends AbstractProjectViewPaneWithAsyncSupport { super(project); } + @Override + protected void configureAsyncSupport(@NotNull AsyncProjectViewSupport support) { + support.setMultiSelectionEnabled(false); + } + @NotNull @Override public String getTitle() { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPaneWithAsyncSupport.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPaneWithAsyncSupport.java index 18f3a5bc7364..197f266b33f0 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPaneWithAsyncSupport.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPaneWithAsyncSupport.java @@ -94,6 +94,7 @@ public abstract class AbstractProjectViewPaneWithAsyncSupport extends AbstractPr } myTreeStructure = createStructure(); myAsyncSupport = new AsyncProjectViewSupport(this, myProject, myTreeStructure, createComparator()); + configureAsyncSupport(myAsyncSupport); myAsyncSupport.setModelTo(myTree); initTree(); @@ -120,6 +121,10 @@ public abstract class AbstractProjectViewPaneWithAsyncSupport extends AbstractPr return myComponent; } + @ApiStatus.Internal + protected void configureAsyncSupport(@NotNull AsyncProjectViewSupport support) { + } + @Override public void installComparator(@NotNull Comparator> comparator) { if (myAsyncSupport != null) { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AsyncProjectViewSupport.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AsyncProjectViewSupport.java index 9cef492bf9aa..90e43737cbd9 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AsyncProjectViewSupport.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AsyncProjectViewSupport.java @@ -48,6 +48,7 @@ public final class AsyncProjectViewSupport { private final ProjectFileNodeUpdater myNodeUpdater; private final StructureTreeModel myStructureTreeModel; private final AsyncTreeModel myAsyncTreeModel; + private boolean myMultiSelectionEnabled = true; public AsyncProjectViewSupport(@NotNull Disposable parent, @NotNull Project project, @@ -219,12 +220,16 @@ public final class AsyncProjectViewSupport { myAsyncTreeModel.accept(visitor).onProcessed(path -> myAsyncTreeModel.onValidThread(task)); } - private static boolean selectPaths(@NotNull JTree tree, @NotNull List paths, @NotNull TreeVisitor visitor) { + public void setMultiSelectionEnabled(boolean enabled) { + myMultiSelectionEnabled = enabled; + } + + private boolean selectPaths(@NotNull JTree tree, @NotNull List paths, @NotNull TreeVisitor visitor) { if (paths.isEmpty()) { SelectInProjectViewImplKt.getLOG().debug("Nothing to select"); return false; } - if (paths.size() > 1) { + if (paths.size() > 1 && myMultiSelectionEnabled) { if (visitor instanceof ProjectViewNodeVisitor nodeVisitor) { return selectPaths(tree, new SelectionDescriptor(nodeVisitor.getElement(), nodeVisitor.getFile(), paths)); } @@ -232,6 +237,9 @@ public final class AsyncProjectViewSupport { return selectPaths(tree, new SelectionDescriptor(null, fileVisitor.getElement(), paths)); } } + if (!myMultiSelectionEnabled) { + SelectInProjectViewImplKt.getLOG().debug("Selecting only the first path because multi-selection is disabled"); + } TreePath path = paths.get(0); tree.expandPath(path); // request to expand found path TreeUtil.selectPaths(tree, path); // select and scroll to center diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java index 4d5f89962249..274e1c80365f 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java @@ -44,6 +44,11 @@ public class ProjectViewPane extends AbstractProjectViewPaneWithAsyncSupport { super(project); } + @Override + public void configureAsyncSupport(@NotNull AsyncProjectViewSupport support) { + support.setMultiSelectionEnabled(false); + } + @NotNull @Override public String getTitle() {