[ij-light] IJPL-218999 Preserve ProjectViewPane state when the pane is removed from the ProjectView

IJ-light switches "local" project pane to "RD" project pane, and the state should be preserved during this switch.

GitOrigin-RevId: e2105ee23f5b4d10510a74df0ba3cff543a5c6f7
This commit is contained in:
Andrei.Kuznetsov
2025-11-19 17:53:21 +00:00
committed by intellij-monorepo-bot
parent c0e373e852
commit 13cfdc5aff
6 changed files with 52 additions and 29 deletions
@@ -17,37 +17,44 @@ package com.intellij.projectView;
import com.intellij.JavaTestUtil;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.impl.ProjectViewImpl;
import com.intellij.ide.projectView.impl.ProjectViewPane;
import com.intellij.testFramework.TestSourceBasedTestCase;
import com.intellij.openapi.vfs.VirtualFile;
public class ProjectViewSwitchingTest extends TestSourceBasedTestCase {
public class ProjectViewSwitchingTest extends AbstractProjectViewTest {
@Override
protected String getTestPath() {
return "projectView";
}
public void testSelectProject() {
public void testRemoveAddProjectPane() {
ProjectView projectView = ProjectView.getInstance(getProject());
projectView.changeView(ProjectViewPane.ID);
assertEquals(ProjectViewPane.ID, projectView.getCurrentViewId());
//FavoritesManager favoritesManager = FavoritesManager.getInstance(getProject());
//favoritesManager.createNewList("xxxx");
//
//AbstractProjectViewPane currentPane = projectView.getCurrentProjectViewPane();
//assertEquals(FavoritesProjectViewPane.ID, currentPane.getId());
//assertEquals("xxxx", currentPane.getSubId());
//
//favoritesManager.createNewList("yyyy");
//currentPane = projectView.getCurrentProjectViewPane();
//assertEquals(FavoritesProjectViewPane.ID, currentPane.getId());
//assertEquals("yyyy", currentPane.getSubId());
//
//favoritesManager.removeFavoritesList("xxxx");
//currentPane = projectView.getCurrentProjectViewPane();
//assertEquals(FavoritesProjectViewPane.ID, currentPane.getId());
//assertEquals("yyyy", currentPane.getSubId());
VirtualFile class1 = getContentRoot().findFileByRelativePath("src/com/package1/Class1.java");
selectFile(class1);
String expectedTreeStructure = """
-PsiDirectory: removeAddProjectPane
-PsiDirectory: src
-PsiDirectory: com
-PsiDirectory: package1
Class1
+Class2.java
Class4.java
Form1
+External Libraries
""";
createTreeTest().assertStructure(expectedTreeStructure);
projectView.removeProjectPane(projectView.getProjectViewPaneById(ProjectViewPane.ID));
((ProjectViewImpl)projectView).addProjectPane(new ProjectViewPane(getProject()), true);
projectView.changeView(ProjectViewPane.ID);
// it is important that we create a new instance of the TreeTestUtil (createTreeTest()) here,
// because the old one has captured a reference to the old project view tree
createTreeTest().assertStructure(expectedTreeStructure); // addProjectPane should restore state
}
@Override
@@ -743,6 +743,11 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo
@ApiStatus.Internal
@CalledInAny
public synchronized void addProjectPane(final @NotNull AbstractProjectViewPane pane, boolean restoreState) {
if (idToPane.containsKey(pane.getId())) {
LOG.error("Pane with ID=" + pane.getId() + " already exists. Please remove it first with removeProjectPane(pane).");
removeProjectPane(idToPane.get(pane.getId()));
}
uninitializedPanes.add(pane);
if (restoreState) {
applyUninitializedPaneState(pane);
@@ -771,10 +776,15 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo
@Override
public synchronized void removeProjectPane(@NotNull AbstractProjectViewPane pane) {
ThreadingAssertions.assertEventDispatchThread();
uninitializedPanes.remove(pane);
//assume we are completely initialized here
@NotNull String idToRemove = pane.getId();
var oldPaneState = getPaneState(pane);
if (oldPaneState != null) {
myUninitializedPaneState.put(idToRemove, oldPaneState);
}
uninitializedPanes.remove(pane);
if (!idToPane.containsKey(idToRemove)) return;
for (int i = getContentManager().getContentCount() - 1; i >= 0; i--) {
Content content = getContentManager().getContent(i);
@@ -1523,14 +1533,8 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo
private void writePaneState(@NotNull Element panesElement) {
for (AbstractProjectViewPane pane : idToPane.values()) {
Element paneElement = new Element(ELEMENT_PANE);
paneElement.setAttribute(ATTRIBUTE_ID, pane.getId());
try {
pane.writeExternal(paneElement);
}
catch (WriteExternalException e) {
continue;
}
Element paneElement = getPaneState(pane);
if (paneElement == null) continue;
panesElement.addContent(paneElement);
}
for (Element element : myUninitializedPaneState.values()) {
@@ -1538,6 +1542,18 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo
}
}
private static @Nullable Element getPaneState(AbstractProjectViewPane pane) {
Element paneElement = new Element(ELEMENT_PANE);
paneElement.setAttribute(ATTRIBUTE_ID, pane.getId());
try {
pane.writeExternal(paneElement);
}
catch (WriteExternalException e) {
return null;
}
return paneElement;
}
private static ProjectViewSharedSettings getGlobalOptions() {
return ProjectViewSharedSettings.Companion.getInstance();
}