From: Kirill Kalishev Date: Tue, 1 Dec 2009 13:25:05 +0000 (+0300) Subject: Merge branch 'master' of git@git.labs.intellij.net:idea/community X-Git-Tag: 92.87~10^2 X-Git-Url: https://git.jetbrains.org/?p=idea%2Fcommunity.git;a=commitdiff_plain;h=3c6c38292502442b75b9bf47dc5998019221b523;hp=6775cb305dc135a9cf8c6495b9b799bc2c16b3b5 Merge branch 'master' of git@git.labs.intellij.net:idea/community --- diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java index b670e0812c13..cc464273d976 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java @@ -152,6 +152,9 @@ public class AbstractTreeUi { private boolean myPassthroughMode = false; + private Set myAutoExpandRoots = new HashSet(); + private final RegistryValue myAutoExpandDepth = Registry.get("ide.tree.autoExpandMaxDepth"); + protected void init(AbstractTreeBuilder builder, JTree tree, DefaultTreeModel treeModel, @@ -582,14 +585,43 @@ public class AbstractTreeUi { autoExpand = getBuilder().isAutoExpandNode(descriptor); } + Object element = getElementFromDescriptor(descriptor); + autoExpand = validateAutoExpand(autoExpand, element); + if (!autoExpand && !myTree.isRootVisible()) { - Object element = getElementFromDescriptor(descriptor); if (element != null && element.equals(getTreeStructure().getRootElement())) return true; } return autoExpand; } + private boolean validateAutoExpand(boolean autoExpand, Object element) { + if (autoExpand) { + int distance = getDistanceToAutoExpandRoot(element); + if (distance < 0) { + myAutoExpandRoots.add(element); + } else { + if (distance >= myAutoExpandDepth.asInteger() - 1) { + autoExpand = false; + } + } + } + return autoExpand; + } + + private int getDistanceToAutoExpandRoot(Object element) { + int distance = 0; + + Object eachParent = element; + while (eachParent != null) { + if (myAutoExpandRoots.contains(eachParent)) break; + eachParent = getTreeStructure().getParentElement(eachParent); + distance++; + } + + return eachParent != null ? distance : -1; + } + private boolean isAutoExpand(DefaultMutableTreeNode node) { return isAutoExpand(getDescriptorFrom(node)); } @@ -931,7 +963,7 @@ public class AbstractTreeUi { addSelectionPath(getPathFor(node), true, Condition.TRUE, null); } - doWithUpdaterState(new Runnable() { + processInnerChange(new Runnable() { public void run() { for (TreeNode each : children) { removeNodeFromParent((MutableTreeNode)each, true); @@ -1866,16 +1898,23 @@ public class AbstractTreeUi { private boolean canSmartExpand(DefaultMutableTreeNode node, boolean canSmartExpand) { - return !myNotForSmartExpand.contains(node) && canSmartExpand; + if (!getBuilder().isSmartExpand()) return false; + + boolean smartExpand = !myNotForSmartExpand.contains(node) && canSmartExpand; + return smartExpand ? validateAutoExpand(smartExpand, getElementFor(node)) : false; } - private void processSmartExpand(final DefaultMutableTreeNode node, final boolean canSmartExpand) { - if (!getBuilder().isSmartExpand() || !canSmartExpand(node, canSmartExpand)) return; + private void processSmartExpand(final DefaultMutableTreeNode node, final boolean canSmartExpand, boolean forced) { + if (!getBuilder().isSmartExpand()) return; + + boolean can = canSmartExpand(node, canSmartExpand); + + if (!can && !forced) return; - if (isNodeBeingBuilt(node)) { + if (isNodeBeingBuilt(node) && !forced) { addNodeAction(getElementFor(node), new NodeAction() { public void onReady(DefaultMutableTreeNode node) { - processSmartExpand(node, canSmartExpand); + processSmartExpand(node, canSmartExpand, true); } }, true); } @@ -1883,7 +1922,11 @@ public class AbstractTreeUi { TreeNode child = getChildForSmartExpand(node); if (child != null) { final TreePath childPath = new TreePath(node.getPath()).pathByAddingChild(child); - myTree.expandPath(childPath); + processInnerChange(new Runnable() { + public void run() { + myTree.expandPath(childPath); + } + }); } } } @@ -2147,7 +2190,7 @@ public class AbstractTreeUi { } private void addSelectionPath(final TreePath path, final boolean isAdjustedSelection, final Condition isExpiredAdjustement, @Nullable final Object adjustmentCause) { - doWithUpdaterState(new Runnable() { + processInnerChange(new Runnable() { public void run() { TreePath toSelect = null; @@ -2196,7 +2239,7 @@ public class AbstractTreeUi { private void removeNodeFromParent(final MutableTreeNode node, final boolean willAdjustSelection) { - doWithUpdaterState(new Runnable() { + processInnerChange(new Runnable() { public void run() { if (willAdjustSelection) { final TreePath path = getPathFor(node); @@ -2211,7 +2254,7 @@ public class AbstractTreeUi { } private void expandPath(final TreePath path, final boolean canSmartExpand) { - doWithUpdaterState(new Runnable() { + processInnerChange(new Runnable() { public void run() { if (path.getLastPathComponent() instanceof DefaultMutableTreeNode) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); @@ -2222,7 +2265,7 @@ public class AbstractTreeUi { try { myRequestedExpand = path; myTree.expandPath(path); - processSmartExpand(node, canSmartExpand); + processSmartExpand(node, canSmartExpand, false); } finally { myNotForSmartExpand.remove(node); @@ -2237,13 +2280,16 @@ public class AbstractTreeUi { }); } - private void doWithUpdaterState(Runnable runnable) { - if (myUpdaterState != null) { - myUpdaterState.process(runnable); - } - else { - runnable.run(); + private void processInnerChange(Runnable runnable) { + if (myUpdaterState == null) { + setUpdaterState(new UpdaterTreeState(this)); } + + myUpdaterState.process(runnable); + } + + private boolean isInnerChange() { + return myUpdaterState != null && myUpdaterState.isProcessingNow(); } protected boolean doUpdateNodeDescriptor(final NodeDescriptor descriptor) { @@ -2517,7 +2563,7 @@ public class AbstractTreeUi { sortChildren(parentNode, all, true, false); if (!before.equals(all)) { - doWithUpdaterState(new Runnable() { + processInnerChange(new Runnable() { public void run() { parentNode.removeAllChildren(); for (TreeNode each : all) { @@ -2564,6 +2610,7 @@ public class AbstractTreeUi { if (descriptor == null) return; final Object element = getElementFromDescriptor(descriptor); removeMapping(element, node, null); + myAutoExpandRoots.remove(element); node.setUserObject(null); node.removeAllChildren(); } @@ -3204,8 +3251,9 @@ public class AbstractTreeUi { } private void dropUpdaterStateIfExternalChange() { - if (myUpdaterState != null && !myUpdaterState.isProcessingNow()) { - clearUpdaterState(); + if (!isInnerChange()) { + clearUpdaterState(); + myAutoExpandRoots.clear(); } } @@ -3427,7 +3475,7 @@ public class AbstractTreeUi { getBuilder().expandNodeChildren(node); } - processSmartExpand(node, canSmartExpand(node, true)); + processSmartExpand(node, canSmartExpand(node, true), false); processNodeActionsIfReady(node); } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/UpdaterTreeState.java b/platform/platform-api/src/com/intellij/ide/util/treeView/UpdaterTreeState.java index 885d45b5e4a3..5e61c53e07fd 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/UpdaterTreeState.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/UpdaterTreeState.java @@ -40,11 +40,17 @@ public class UpdaterTreeState { private WeakHashMap myAdjustmentCause2Adjustment = new WeakHashMap(); public UpdaterTreeState(AbstractTreeUi ui) { + this(ui, false); + } + + public UpdaterTreeState(AbstractTreeUi ui, boolean isEmpty) { myUi = ui; - final JTree tree = myUi.getTree(); - putAll(addPaths(tree.getSelectionPaths()), myToSelect); - putAll(addPaths(tree.getExpandedDescendants(new TreePath(tree.getModel().getRoot()))), myToExpand); + if (!isEmpty) { + final JTree tree = myUi.getTree(); + putAll(addPaths(tree.getSelectionPaths()), myToSelect); + putAll(addPaths(tree.getExpandedDescendants(new TreePath(tree.getModel().getRoot()))), myToExpand); + } } private static void putAll(final Set source, final Map target) { diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 07e4cfea1f86..625b0f97e468 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -31,6 +31,7 @@ ide.tree.waitForReadyTimout=250 ide.tree.clearOnHideTime=120000 ide.tree.autoscrollToVCenter=true ide.tree.ensureSelectionOnFocusGained=true +ide.tree.autoExpandMaxDepth=5 ide.tabbedPane.bufferedPaint=true