From 4ff28646298d140cb7bd397c685220d91c310f55 Mon Sep 17 00:00:00 2001 From: Anton Kozub Date: Thu, 26 Jun 2025 14:54:37 +0200 Subject: [PATCH] IDEA-361647 Spring Structure for application.properties: collapse/expand all action GitOrigin-RevId: 4424075431cdf7841b7aa23a3f1a90ffeecacd9c --- .../ide/impl/StructureViewWrapperImpl.kt | 6 +- .../StructureViewComponent.java | 5 +- .../newStructureView/StructureViewExpander.kt | 60 +++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewExpander.kt diff --git a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.kt b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.kt index a25504d860cc..1eea25ae9432 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.kt +++ b/platform/lang-impl/src/com/intellij/ide/impl/StructureViewWrapperImpl.kt @@ -54,7 +54,6 @@ import com.intellij.ui.content.ContentManagerEvent.ContentOperation import com.intellij.ui.content.ContentManagerListener import com.intellij.ui.switcher.QuickActionProvider import com.intellij.util.PlatformUtils -import com.intellij.util.cancelOnDispose import com.intellij.util.concurrency.AppExecutorUtil import com.intellij.util.messages.Topic import com.intellij.util.ui.JBUI @@ -552,6 +551,11 @@ class StructureViewWrapperImpl( } } + @ApiStatus.Internal + fun getStructureView(): StructureView? { + return myStructureView + } + private suspend fun updateHeaderActions(structureView: StructureView?) { myActionGroup.removeAll() val titleActions: List = if (structureView is StructureViewComponent) { diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index c71c29c3fe52..4d1491ea0460 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -422,8 +422,9 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre public final @NotNull List addExpandCollapseActions() { List result = new ArrayList<>(); CommonActionsManager commonActionManager = CommonActionsManager.getInstance(); - result.add(commonActionManager.createExpandAllHeaderAction(getTree())); - result.add(commonActionManager.createCollapseAllHeaderAction(getTree())); + var expander = new StructureViewExpander(myProject); + result.add(commonActionManager.createExpandAllHeaderAction(expander, getTree())); + result.add(commonActionManager.createCollapseAllHeaderAction(expander, getTree())); return result; } diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewExpander.kt b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewExpander.kt new file mode 100644 index 000000000000..74412ada6709 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewExpander.kt @@ -0,0 +1,60 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.ide.structureView.newStructureView + +import com.intellij.ide.TreeExpander +import com.intellij.ide.impl.StructureViewWrapperImpl +import com.intellij.ide.structureView.StructureViewFactory +import com.intellij.ide.structureView.StructureViewFactoryEx +import com.intellij.ide.structureView.impl.StructureViewComposite +import com.intellij.ide.structureView.logical.ExternalElementsProvider +import com.intellij.ide.structureView.logical.LogicalStructureElementsProvider +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiTarget +import com.intellij.util.ui.tree.TreeUtil +import javax.swing.JTree + +internal class StructureViewExpander(val project: Project): TreeExpander { + + override fun canCollapse(): Boolean { + return getActualTree() != null + } + + override fun canExpand(): Boolean { + return getActualTree() != null + } + + override fun collapseAll() { + val tree = getActualTree() ?: return + TreeUtil.collapseAll(tree, true, 1) + } + + override fun expandAll() { + val tree = getActualTree() ?: return + val rootFile = (StructureViewComponent.unwrapValue(tree.model.root) as? PsiElement)?.containingFile?.virtualFile + TreeUtil.promiseExpand(tree, Int.Companion.MAX_VALUE) { path -> + val pathObject = StructureViewComponent.unwrapValue(path.lastPathComponent) + when (pathObject) { + is LogicalStructureElementsProvider<*, *> -> pathObject !is ExternalElementsProvider<*, *> + is PsiElement -> rootFile == null || pathObject.containingFile?.virtualFile == rootFile + is PsiTarget if rootFile != null && pathObject.isValid -> pathObject.navigationElement.containingFile?.virtualFile == rootFile + else -> true + } + } + } + + private fun getActualTree(): JTree? { + val wrapper = (StructureViewFactory.getInstance(project) as? StructureViewFactoryEx) + ?.structureViewWrapper as? StructureViewWrapperImpl ?: return null + val structureView = wrapper.getStructureView() ?: return null + if (structureView is StructureViewComponent) return structureView.tree + if (structureView is StructureViewComposite) { + for (descriptor in structureView.structureViews) { + val oneOfViews = descriptor.structureView as? StructureViewComponent ?: continue + val tree = oneOfViews.tree + if (tree.isShowing) return tree + } + } + return null + } +} \ No newline at end of file