From 3875dae9c9f3309ab4c25888127cf96c909edd7c Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 8 Oct 2009 14:34:02 +0400 Subject: [PATCH 1/3] TreeUi: tests factored take 1 --- .../util/treeView/AbstractTreeBuilder.java | 6 +- .../ide/util/treeView/AbstractTreeUi.java | 127 ++++++++++++++---- .../util/treeView/AbstractTreeUpdater.java | 2 +- .../intellij/ide/util/treeView/TreeState.java | 10 +- .../ide/util/treeView/UpdaterTreeState.java | 52 ++++--- .../filtered/FilteringTreeBuilder.java | 37 +++-- .../filtered/FilteringTreeStructure.java | 7 +- 7 files changed, 178 insertions(+), 63 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java index 425a540e7b32..74b9feaa4cc5 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeBuilder.java @@ -315,10 +315,14 @@ public class AbstractTreeBuilder implements Disposable { UIUtil.invokeLaterIfNeeded(runnable); } - public final ActionCallback getReady() { + public final ActionCallback getIntialized() { return myUi.getInitialized(); } + public final ActionCallback getReady(Object requestor) { + return myUi.getReady(requestor); + } + protected void sortChildren(Comparator nodeComparator, DefaultMutableTreeNode node, ArrayList children) { Collections.sort(children, nodeComparator); } 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 a3599b6d38c6..3d9876bfc65d 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 @@ -42,7 +42,7 @@ import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -class AbstractTreeUi { +public class AbstractTreeUi { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.treeView.AbstractTreeBuilder"); protected JTree myTree;// protected for TestNG @SuppressWarnings({"WeakerAccess"}) protected DefaultTreeModel myTreeModel; @@ -128,6 +128,7 @@ class AbstractTreeUi { private Set myNotForSmartExpand = new HashSet(); private TreePath myRequestedExpand; private ActionCallback myInitialized = new ActionCallback(); + private Map myReadyCallbacks = new WeakHashMap(); protected final void init(AbstractTreeBuilder builder, JTree tree, @@ -642,6 +643,8 @@ class AbstractTreeUi { } final void updateSubtreeNow(TreeUpdatePass pass, boolean canSmartExpand) { + System.out.println("AbstractTreeUi.updateSubtreeNow pass=" + pass); + maybeSetBusyAndScheduleWaiterForReady(true); initRootNodeNowIfNeeded(pass); @@ -1102,7 +1105,7 @@ class AbstractTreeUi { } private boolean hasSheduledUpdates() { - return getUpdater().hasNodesToUpdate() || isLoadingInBackground(); + return getUpdater().hasNodesToUpdate() || isLoadingInBackgroundNow(); } public boolean isReady() { @@ -1130,15 +1133,23 @@ class AbstractTreeUi { if (isReleased()) return; if (isReady()) { - if (myTree.isShowing()) { + if (myTree.isShowing() || myUpdateIfInactive) { myInitialized.setDone(); + } + if (myTree.isShowing()) { if (isReady()) { if (getBuilder().isToEnsureSelectionOnFocusGained() && Registry.is("ide.tree.ensureSelectionOnFocusGained")) { TreeUtil.ensureSelection(myTree); } } } + + if (myInitialized.isDone()) { + for (ActionCallback each : getReadyCallbacks(true)) { + each.setDone(); + } + } } } @@ -1288,6 +1299,14 @@ class AbstractTreeUi { return myInitialized; } + public ActionCallback getReady(Object requestor) { + if (isReady()) { + return new ActionCallback.Done(); + } else { + return addReadyCallback(requestor); + } + } + private void addToUpdating(DefaultMutableTreeNode node) { synchronized (myUpdatingChildren) { myUpdatingChildren.add(node); @@ -1306,6 +1325,12 @@ class AbstractTreeUi { } } + boolean hasUpdatingNow() { + synchronized (myUpdatingChildren) { + return myUpdatingChildren.size() > 0; + } + } + public Map getNodeActions() { return myNodeActions; } @@ -1326,6 +1351,10 @@ class AbstractTreeUi { return result; } + public boolean hasNodesToUpdate() { + return getUpdater().hasNodesToUpdate() || hasUpdatingNow() || isLoadingInBackgroundNow(); + } + static class ElementNode extends DefaultMutableTreeNode { Set myElements = new HashSet(); @@ -1393,7 +1422,7 @@ class AbstractTreeUi { } } - private boolean isLoadingInBackground() { + private boolean isLoadingInBackgroundNow() { synchronized (myLoadingParents) { return myLoadingParents.size() > 0; } @@ -1739,25 +1768,7 @@ class AbstractTreeUi { removeNodeFromParent(childNode, selectedIndex >= 0); disposeNode(childNode); - if (selectedIndex >= 0) { - if (parentNode.getChildCount() > 0) { - if (parentNode.getChildCount() > selectedIndex) { - TreeNode newChildNode = parentNode.getChildAt(selectedIndex); - if (isValidForSelectionAdjusting(newChildNode)) { - addSelectionPath(new TreePath(myTreeModel.getPathToRoot(newChildNode)), true, getExpiredElementCondition(disposedElement)); - } - } - else { - TreeNode newChild = parentNode.getChildAt(parentNode.getChildCount() - 1); - if (isValidForSelectionAdjusting(newChild)) { - addSelectionPath(new TreePath(myTreeModel.getPathToRoot(newChild)), true, getExpiredElementCondition(disposedElement)); - } - } - } - else { - addSelectionPath(new TreePath(myTreeModel.getPathToRoot(parentNode)), true, getExpiredElementCondition(disposedElement)); - } - } + adjustSelectionOnChildRemove(parentNode, selectedIndex, disposedElement); } else { elementToIndexMap.remove(getBuilder().getTreeStructureElement(childDesc)); @@ -1771,6 +1782,36 @@ class AbstractTreeUi { return new ActionCallback.Done(); } + private void adjustSelectionOnChildRemove(DefaultMutableTreeNode parentNode, int selectedIndex, Object disposedElement) { + DefaultMutableTreeNode node = getNodeForElement(disposedElement, false); + if (node != null && isValidForSelectionAdjusting(node)) { + Object newElement = getElementFor(node); + addSelectionPath(getPathFor(node), true, getExpiredElementCondition(newElement)); + return; + } + + + if (selectedIndex >= 0) { + if (parentNode.getChildCount() > 0) { + if (parentNode.getChildCount() > selectedIndex) { + TreeNode newChildNode = parentNode.getChildAt(selectedIndex); + if (isValidForSelectionAdjusting(newChildNode)) { + addSelectionPath(new TreePath(myTreeModel.getPathToRoot(newChildNode)), true, getExpiredElementCondition(disposedElement)); + } + } + else { + TreeNode newChild = parentNode.getChildAt(parentNode.getChildCount() - 1); + if (isValidForSelectionAdjusting(newChild)) { + addSelectionPath(new TreePath(myTreeModel.getPathToRoot(newChild)), true, getExpiredElementCondition(disposedElement)); + } + } + } + else { + addSelectionPath(new TreePath(myTreeModel.getPathToRoot(parentNode)), true, getExpiredElementCondition(disposedElement)); + } + } + } + private boolean isValidForSelectionAdjusting(TreeNode node) { if (isLoadingNode(node)) return true; @@ -2437,6 +2478,7 @@ class AbstractTreeUi { private void selectVisible(Object element, final Runnable onDone, boolean addToSelection, boolean canBeCentered, final boolean scroll) { final DefaultMutableTreeNode toSelect = getNodeForElement(element, false); + if (toSelect == null) { runDone(onDone); return; @@ -2663,6 +2705,22 @@ class AbstractTreeUi { } + private String asString(DefaultMutableTreeNode node) { + if (node == null) return null; + + StringBuffer children = new StringBuffer(node.toString()); + children.append(" ["); + for (int i = 0; i < node.getChildCount(); i++) { + children.append(node.getChildAt(i)); + if (i < node.getChildCount() - 1) { + children.append(","); + } + } + children.append("]"); + + return children.toString(); + } + @Nullable private Object getElementFor(Object node) { if (!(node instanceof DefaultMutableTreeNode)) return null; @@ -3083,4 +3141,27 @@ class AbstractTreeUi { UpdaterTreeState getUpdaterState() { return myUpdaterState; } + + private ActionCallback addReadyCallback(Object requestor) { + synchronized (myReadyCallbacks) { + ActionCallback cb = myReadyCallbacks.get(requestor); + if (cb == null) { + cb = new ActionCallback(); + myReadyCallbacks.put(requestor, cb); + } + + return cb; + } + } + + private ActionCallback[] getReadyCallbacks(boolean clear) { + synchronized (myReadyCallbacks) { + ActionCallback[] result = myReadyCallbacks.values().toArray(new ActionCallback[myReadyCallbacks.size()]); + if (clear) { + myReadyCallbacks.clear(); + } + return result; + } + } + } diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUpdater.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUpdater.java index cd60a412aef1..07e797d0b06b 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUpdater.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUpdater.java @@ -83,7 +83,7 @@ public class AbstractTreeUpdater implements Disposable, Activatable { } public boolean hasNodesToUpdate() { - return myNodeQueue.size() > 0 || !myUpdateQueue.isEmpty(); + return myNodeQueue.size() > 0; } public void dispose() { diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java index 67fa43305ba9..bb86f11473fe 100644 --- a/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java +++ b/platform/platform-api/src/com/intellij/ide/util/treeView/TreeState.java @@ -229,7 +229,7 @@ public class TreeState implements JDOMExternalizable { } private void applyExpanded(final TreeFacade tree, final Object root) { - tree.getReady().doWhenDone(new Runnable() { + tree.getIntialized().doWhenDone(new Runnable() { public void run() { _applyExpanded(tree, root); } @@ -360,7 +360,7 @@ public class TreeState implements JDOMExternalizable { } interface TreeFacade { - ActionCallback getReady(); + ActionCallback getIntialized(); ActionCallback expand(DefaultMutableTreeNode node); } @@ -382,7 +382,7 @@ public class TreeState implements JDOMExternalizable { return new ActionCallback.Done(); } - public ActionCallback getReady() { + public ActionCallback getIntialized() { return new ActionCallback.Done(); } } @@ -395,8 +395,8 @@ public class TreeState implements JDOMExternalizable { myBuilder = builder; } - public ActionCallback getReady() { - return myBuilder.getReady(); + public ActionCallback getIntialized() { + return myBuilder.getIntialized(); } public ActionCallback expand(DefaultMutableTreeNode 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 dde9c30ac69c..79305738c32d 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 @@ -124,29 +124,13 @@ public class UpdaterTreeState { } public boolean restore(@Nullable DefaultMutableTreeNode actionNode) { - if (isProcessingNow() || !myCanRunRestore) return false; + if (isProcessingNow() || !myCanRunRestore || myUi.hasNodesToUpdate()) return false; + + invalidateToSelectWithRefsToParent(actionNode); myProcessingNow = true; - - if (actionNode != null) { - Object readyElement = myUi.getElementFor(actionNode); - if (readyElement != null) { - Iterator toSelect = myToSelect.keySet().iterator(); - while (toSelect.hasNext()) { - Object eachToSelect = toSelect.next(); - if (readyElement.equals(myUi.getTreeStructure().getParentElement(eachToSelect))) { - List children = myUi.getLoadedChildrenFor(readyElement); - if (!children.contains(eachToSelect)) { - toSelect.remove(); - if (!myToSelect.containsKey(readyElement)) { - addAdjustedSelection(eachToSelect, Condition.FALSE); - } - } - } - } - } - } + System.out.println("UpdaterTreeState.restore actionNode=" + actionNode); final Object[] toSelect = getToSelect(); final Object[] toExpand = getToExpand(); @@ -160,8 +144,10 @@ public class UpdaterTreeState { final Set originallySelected = myUi.getSelectedElements(); + System.out.println("UpdaterTreeState.restore toSelect=" + Arrays.asList(toSelect) + " now selected=" + originallySelected); myUi._select(toSelect, new Runnable() { public void run() { + System.out.println("UpdaterTreeState.run finished selecting=" + Arrays.asList(toSelect) + " now selected=" + myUi.getSelectedElements() + " adjuested=" + adjusted); processUnsuccessfulSelections(toSelect, new Function() { public Object fun(final Object o) { if (myUi.getTree().isRootVisible() || !myUi.getTreeStructure().getRootElement().equals(o)) { @@ -190,6 +176,29 @@ public class UpdaterTreeState { return true; } + private void invalidateToSelectWithRefsToParent(DefaultMutableTreeNode actionNode) { + if (actionNode != null) { + Object readyElement = myUi.getElementFor(actionNode); + if (readyElement != null) { + Iterator toSelect = myToSelect.keySet().iterator(); + while (toSelect.hasNext()) { + Object eachToSelect = toSelect.next(); + if (readyElement.equals(myUi.getTreeStructure().getParentElement(eachToSelect))) { + List children = myUi.getLoadedChildrenFor(readyElement); + if (!children.contains(eachToSelect)) { + System.out.println(" removed from toSelect node=" + eachToSelect); + toSelect.remove(); + if (!myToSelect.containsKey(readyElement) && !myUi.getSelectedElements().contains(eachToSelect)) { + addAdjustedSelection(eachToSelect, Condition.FALSE); + System.out.println(" addToAdjusted node=" + eachToSelect); + } + } + } + } + } + } + } + void beforeSubtreeUpdate() { myCanRunRestore = true; } @@ -204,6 +213,8 @@ public class UpdaterTreeState { successfulSelections.retainAll(selected); wasFullyRejected = successfulSelections.size() == 0; + } else if (selected.size() == 0 && originallySelected.size() == 0) { + wasFullyRejected = true; } if (wasFullyRejected && selected.size() > 0) return; @@ -317,6 +328,7 @@ public class UpdaterTreeState { } public void addAdjustedSelection(final Object element, Condition isExpired) { + System.out.println("UpdaterTreeState.addAdjustedSelection " + element); myAdjustedSelection.put(element, isExpired); } diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java index eda251d76f51..87404a69257e 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java @@ -102,23 +102,38 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { } } - private ActionCallback refilterNow(Object preferredSelection, final boolean adjustSelection) { + private ActionCallback refilterNow(final Object preferredSelection, final boolean adjustSelection) { final ActionCallback result = new ActionCallback(); - Object selectedObject = getSelected(); - - final Ref toSelect = new Ref(isSelectable(selectedObject) ? selectedObject : null); - if (preferredSelection != null) { - toSelect.set(preferredSelection); - } - - ((FilteringTreeStructure)getTreeStructure()).refilter(); updateFromRoot(); - result.setDone(); + getReady(this).doWhenDone(new Runnable() { + public void run() { + System.out.println("ready=" + getUi().isReady() + " preferred=" + preferredSelection); + if (adjustSelection && preferredSelection != null) { + FilteringTreeStructure.Node node = ((FilteringTreeStructure)getTreeStructure()).getVisibleNodeFor(preferredSelection); + if (node != null) { + select(node, new Runnable() { + public void run() { + result.setDone(); + } + }); + } + } else { + result.setDone(); + } + } + }); + + return result; + } + + private void select(boolean adjustSelection, final Ref toSelect) { if (adjustSelection) { + System.out.println("FilteringTreeBuilder.select toSelect=" + toSelect.get()); + boolean wasSelected = false; if (toSelect.get() != null && isSelectable(toSelect.get()) && isSimpleTree()) { wasSelected = ((SimpleTree)myTree).select(this, new SimpleNodeVisitor() { @@ -173,8 +188,6 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { myLastSuccessfulSelect = getSelected(); } } - - return result; } //todo kirillk diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeStructure.java b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeStructure.java index 652d80fd03c6..e5fb05caafdb 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeStructure.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeStructure.java @@ -79,6 +79,11 @@ public class FilteringTreeStructure extends AbstractTreeStructure { return myDelegate; } + @Override + public String toString() { + return String.valueOf(getDelegate()); + } + @Override public boolean isContentHighlighted() { if (myDelegate instanceof SimpleNode) { @@ -152,7 +157,7 @@ public class FilteringTreeStructure extends AbstractTreeStructure { } public Object[] getEqualityObjects() { - return NONE; + return new Object[] {myDelegate}; } } From 67b2b4a4f30983a113bd05f60bdaa3e630db0455 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 8 Oct 2009 19:11:15 +0400 Subject: [PATCH 2/3] TreeUi: misc tests and fixes --- .../ide/util/treeView/AbstractTreeUi.java | 23 ++++- .../ide/util/treeView/UpdaterTreeState.java | 7 -- .../filtered/FilteringTreeBuilder.java | 85 ++++--------------- 3 files changed, 37 insertions(+), 78 deletions(-) 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 3d9876bfc65d..52c2ebf23308 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 @@ -643,8 +643,6 @@ public class AbstractTreeUi { } final void updateSubtreeNow(TreeUpdatePass pass, boolean canSmartExpand) { - System.out.println("AbstractTreeUi.updateSubtreeNow pass=" + pass); - maybeSetBusyAndScheduleWaiterForReady(true); initRootNodeNowIfNeeded(pass); @@ -1813,6 +1811,8 @@ public class AbstractTreeUi { } private boolean isValidForSelectionAdjusting(TreeNode node) { + if (!myTree.isRootVisible() && getRootNode() == node) return false; + if (isLoadingNode(node)) return true; final Object elementInTree = getElementFor(node); @@ -2376,7 +2376,14 @@ public class AbstractTreeUi { if (!addToSelection) { myTree.clearSelection(); } - addNext(elementsToSelect, 0, onDone, originalRows, deferred, scrollToVisible, canSmartExpand); + addNext(elementsToSelect, 0, new Runnable() { + public void run() { + if (getTree().isSelectionEmpty()) { + restoreSelection(currentElements); + } + runDone(onDone); + } + }, originalRows, deferred, scrollToVisible, canSmartExpand); } else { addToDeferred(elementsToSelect, onDone); @@ -2385,6 +2392,16 @@ public class AbstractTreeUi { }); } + private void restoreSelection(Set selection) { + for (Object each : selection) { + DefaultMutableTreeNode node = getNodeForElement(each, false); + if (node != null && isValidForSelectionAdjusting(node)) { + addSelectionPath(getPathFor(node), false, null); + } + } + } + + private void addToDeferred(final Object[] elementsToSelect, final Runnable onDone) { myDeferredSelections.clear(); myDeferredSelections.add(new Runnable() { 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 79305738c32d..4441ed412ff0 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 @@ -130,8 +130,6 @@ public class UpdaterTreeState { myProcessingNow = true; - System.out.println("UpdaterTreeState.restore actionNode=" + actionNode); - final Object[] toSelect = getToSelect(); final Object[] toExpand = getToExpand(); @@ -144,10 +142,8 @@ public class UpdaterTreeState { final Set originallySelected = myUi.getSelectedElements(); - System.out.println("UpdaterTreeState.restore toSelect=" + Arrays.asList(toSelect) + " now selected=" + originallySelected); myUi._select(toSelect, new Runnable() { public void run() { - System.out.println("UpdaterTreeState.run finished selecting=" + Arrays.asList(toSelect) + " now selected=" + myUi.getSelectedElements() + " adjuested=" + adjusted); processUnsuccessfulSelections(toSelect, new Function() { public Object fun(final Object o) { if (myUi.getTree().isRootVisible() || !myUi.getTreeStructure().getRootElement().equals(o)) { @@ -186,11 +182,9 @@ public class UpdaterTreeState { if (readyElement.equals(myUi.getTreeStructure().getParentElement(eachToSelect))) { List children = myUi.getLoadedChildrenFor(readyElement); if (!children.contains(eachToSelect)) { - System.out.println(" removed from toSelect node=" + eachToSelect); toSelect.remove(); if (!myToSelect.containsKey(readyElement) && !myUi.getSelectedElements().contains(eachToSelect)) { addAdjustedSelection(eachToSelect, Condition.FALSE); - System.out.println(" addToAdjusted node=" + eachToSelect); } } } @@ -328,7 +322,6 @@ public class UpdaterTreeState { } public void addAdjustedSelection(final Object element, Condition isExpired) { - System.out.println("UpdaterTreeState.addAdjustedSelection " + element); myAdjustedSelection.put(element, isExpired); } diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java index 87404a69257e..ca9f2331a1b0 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java @@ -6,16 +6,17 @@ import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Ref; import com.intellij.ui.speedSearch.ElementFilter; -import com.intellij.ui.treeStructure.*; +import com.intellij.ui.treeStructure.PatchedDefaultMutableTreeNode; +import com.intellij.ui.treeStructure.SimpleTree; +import com.intellij.ui.treeStructure.Tree; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; -import javax.swing.*; import java.util.Comparator; public class FilteringTreeBuilder extends AbstractTreeBuilder { @@ -105,18 +106,22 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { private ActionCallback refilterNow(final Object preferredSelection, final boolean adjustSelection) { final ActionCallback result = new ActionCallback(); - ((FilteringTreeStructure)getTreeStructure()).refilter(); + getFilteredStructure().refilter(); updateFromRoot(); getReady(this).doWhenDone(new Runnable() { public void run() { - System.out.println("ready=" + getUi().isReady() + " preferred=" + preferredSelection); + Object toSelect = preferredSelection != null ? preferredSelection : myLastSuccessfulSelect; - if (adjustSelection && preferredSelection != null) { - FilteringTreeStructure.Node node = ((FilteringTreeStructure)getTreeStructure()).getVisibleNodeFor(preferredSelection); - if (node != null) { - select(node, new Runnable() { + if (adjustSelection && toSelect != null) { + final FilteringTreeStructure.Node nodeToSelect = getFilteredStructure().getVisibleNodeFor(toSelect); + + if (nodeToSelect != null) { + select(nodeToSelect, new Runnable() { public void run() { + if (getSelectedElements().contains(nodeToSelect)) { + myLastSuccessfulSelect = getOriginalNode(nodeToSelect); + } result.setDone(); } }); @@ -130,64 +135,8 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { return result; } - private void select(boolean adjustSelection, final Ref toSelect) { - if (adjustSelection) { - System.out.println("FilteringTreeBuilder.select toSelect=" + toSelect.get()); - - boolean wasSelected = false; - if (toSelect.get() != null && isSelectable(toSelect.get()) && isSimpleTree()) { - wasSelected = ((SimpleTree)myTree).select(this, new SimpleNodeVisitor() { - public boolean accept(SimpleNode simpleNode) { - if (simpleNode instanceof FilteringTreeStructure.Node) { - FilteringTreeStructure.Node node = (FilteringTreeStructure.Node)simpleNode; - return node.getDelegate().equals(toSelect.get()); - } - else { - return false; - } - } - }, true); - } - - if (!wasSelected && isSimpleTree()) { - ((SimpleTree)myTree).select(this, new SimpleNodeVisitor() { - public boolean accept(SimpleNode simpleNode) { - if (simpleNode instanceof FilteringTreeStructure.Node) { - - final boolean isRoot = getTreeStructure().getRootElement() == simpleNode; - if (isRoot && !myTree.isRootVisible()) return false; - - FilteringTreeStructure.Node node = (FilteringTreeStructure.Node)simpleNode; - if (isSelectable(node.getDelegate())) { - return true; - } - } - else { - return false; - } - return false; - } - }, true); - } - - if (!wasSelected && myLastSuccessfulSelect != null && isSimpleTree()) { - wasSelected = ((SimpleTree)myTree).select(this, new SimpleNodeVisitor() { - public boolean accept(SimpleNode simpleNode) { - if (simpleNode instanceof FilteringTreeStructure.Node) { - Object object = ((FilteringTreeStructure.Node)simpleNode).getDelegate(); - return myLastSuccessfulSelect.equals(object); - } - return false; - } - }, true); - if (wasSelected) { - myLastSuccessfulSelect = getSelected(); - } - } - else if (wasSelected) { - myLastSuccessfulSelect = getSelected(); - } - } + private FilteringTreeStructure getFilteredStructure() { + return ((FilteringTreeStructure)getTreeStructure()); } //todo kirillk @@ -207,7 +156,7 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { } public FilteringTreeStructure.Node getVisibleNodeFor(Object nodeObject) { - return ((FilteringTreeStructure)getTreeStructure()).getVisibleNodeFor(nodeObject); + return getFilteredStructure().getVisibleNodeFor(nodeObject); } public Object getOriginalNode(Object node) { From 0c0b0ec047167dfafb51c91e8525cc103eb71825 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 8 Oct 2009 19:12:39 +0400 Subject: [PATCH 3/3] MUQ does not need to be modality-state awaree --- .../src/com/intellij/util/ui/update/MergingUpdateQueue.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java b/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java index 9bfd5fb7d209..050a4771b7f1 100644 --- a/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java +++ b/platform/platform-api/src/com/intellij/util/ui/update/MergingUpdateQueue.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.util.Disposer; import com.intellij.util.Alarm; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -227,7 +228,7 @@ public class MergingUpdateQueue implements Runnable, Disposable, Activatable { }; if (myExecuteInDispatchThread && invokeLaterIfNotDispatch && !ApplicationManager.getApplication().isDispatchThread()) { - ApplicationManager.getApplication().invokeLater(toRun, ModalityState.NON_MODAL); + UIUtil.invokeLaterIfNeeded(toRun); } else { toRun.run();