| package com.intellij.ide.util.treeView; |
| |
| import com.intellij.openapi.util.ActionCallback; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.openapi.util.Ref; |
| import com.intellij.ui.TreeUIHelper; |
| import com.intellij.ui.speedSearch.ElementFilter; |
| import com.intellij.ui.treeStructure.*; |
| import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder; |
| import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.LinkedHashMap; |
| |
| /** |
| * @author Kirill Kalishev |
| * @author Konstantin Bulenkov |
| */ |
| public class FilteringTreeBuilderTest extends BaseTreeTestCase { |
| private FilteringTreeBuilder myBuilder; |
| private MyFilter myFilter; |
| private Node myRoot; |
| private SimpleTreeStructure myStructure; |
| |
| public FilteringTreeBuilderTest() { |
| super(false, false); |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| myTree = new SimpleTree() { |
| @Override |
| protected void configureUiHelper(final TreeUIHelper helper) { |
| } |
| }; |
| |
| myFilter = new MyFilter(); |
| myRoot = new Node(null, "/"); |
| myStructure = new SimpleTreeStructure.Impl(myRoot); |
| } |
| |
| private void initBuilder() throws Exception { |
| myBuilder = new FilteringTreeBuilder(myTree, myFilter, myStructure, AlphaComparator.INSTANCE) { |
| @Override |
| protected AbstractTreeUpdater createUpdater() { |
| return _createUpdater(this); |
| } |
| }; |
| |
| showTree(); |
| |
| Disposer.register(getRootDisposable(), myBuilder); |
| } |
| |
| public void testFilter() throws Exception { |
| myTree.setRootVisible(false); |
| |
| final Node f1 = myRoot.addChild("folder1"); |
| f1.addChild("file11"); |
| f1.addChild("file12"); |
| Node f11 = f1.addChild("folder11"); |
| f11.addChild("element111"); |
| myRoot.addChild("folder2").addChild("file21"); |
| |
| initBuilder(); |
| |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " file11\n" |
| + " file12\n" |
| + " -folder11\n" |
| + " element111\n" |
| + " -folder2\n" |
| + " file21\n"); |
| |
| update("", findNode("file11")); |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " [file11]\n" |
| + " file12\n" |
| + " -folder11\n" |
| + " element111\n" |
| + " -folder2\n" |
| + " file21\n"); |
| |
| updateFilter("f"); |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " [file11]\n" |
| + " file12\n" |
| + " folder11\n" |
| + " -folder2\n" |
| + " file21\n"); |
| |
| updateFilter("fo"); |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " [folder11]\n" |
| + " folder2\n"); |
| |
| updateFilter("fo_"); |
| assertTree("+/\n"); |
| |
| updateFilter(""); |
| assertTree("-/\n" |
| + " -[folder1]\n" |
| + " file11\n" |
| + " file12\n" |
| + " -folder11\n" |
| + " element111\n" |
| + " -folder2\n" |
| + " file21\n"); |
| |
| |
| select("element111"); |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " file11\n" |
| + " file12\n" |
| + " -folder11\n" |
| + " [element111]\n" |
| + " -folder2\n" |
| + " file21\n"); |
| |
| updateFilter("folder2"); |
| assertTree("-/\n" |
| + " [folder2]\n"); |
| |
| updateFilter(""); |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " file11\n" |
| + " file12\n" |
| + " -folder11\n" |
| + " element111\n" |
| + " -[folder2]\n" |
| + " file21\n"); |
| |
| updateFilter("file1"); |
| assertTree("-/\n" |
| + " -[folder1]\n" |
| + " file11\n" |
| + " file12\n"); |
| |
| select("file12"); |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " file11\n" |
| + " [file12]\n"); |
| |
| updateFilter(""); |
| assertTree("-/\n" |
| + " -folder1\n" |
| + " file11\n" |
| + " [file12]\n" |
| + " -folder11\n" |
| + " element111\n" |
| + " -folder2\n" |
| + " file21\n"); |
| |
| } |
| |
| private void select(String element) throws Exception { |
| FilteringTreeStructure.FilteringNode node = myBuilder.getVisibleNodeFor(findNode(element)); |
| select(new Object[] {node}, false); |
| } |
| |
| private void updateFilter(final String text) throws Exception { |
| update(text, null); |
| } |
| |
| private void update(final String text, @Nullable final Object selection) throws Exception { |
| myFilter.update(text, selection); |
| } |
| |
| private class Node extends CachingSimpleNode { |
| |
| private final LinkedHashMap<String, Node> myKids = new LinkedHashMap<String, Node>(); |
| |
| private Node(final SimpleNode aParent, String name) { |
| super(aParent); |
| myName = name; |
| } |
| |
| public Node addChild(String name) { |
| if (!myKids.containsKey(name)) { |
| myKids.put(name, new Node(this, name)); |
| } |
| |
| return myKids.get(name); |
| } |
| |
| @Override |
| protected void doUpdate() { |
| setPlainText(myName); |
| } |
| |
| @Override |
| protected SimpleNode[] buildChildren() { |
| return myKids.isEmpty() ? NO_CHILDREN : myKids.values().toArray(new Node[myKids.size()]); |
| } |
| |
| @Override |
| public String toString() { |
| return myName; |
| } |
| |
| @Override |
| protected void updateFileStatus() { |
| |
| } |
| } |
| |
| private Object findNode(final String name) { |
| final Ref<Object> node = new Ref<Object>(); |
| ((SimpleTree)myTree).accept(myBuilder, new SimpleNodeVisitor() { |
| @Override |
| public boolean accept(final SimpleNode simpleNode) { |
| if (name.equals(simpleNode.toString())) { |
| node.set(myBuilder.getOriginalNode(simpleNode)); |
| return true; |
| } else { |
| return false; |
| } |
| } |
| }); |
| |
| return node.get(); |
| } |
| |
| |
| private static class MyFilter extends ElementFilter.Active.Impl { |
| |
| String myPattern = ""; |
| |
| @Override |
| public boolean shouldBeShowing(final Object value) { |
| return value.toString().startsWith(myPattern); |
| } |
| |
| public ActionCallback update(final String pattern, Object selection) { |
| myPattern = pattern; |
| return fireUpdate(selection, true, false); |
| } |
| } |
| |
| @Override |
| AbstractTreeBuilder getBuilder() { |
| return myBuilder; |
| } |
| } |
| |
| |