diff -r f080832b3afd junit/src/org/netbeans/modules/junit/output/NodeStateUtilities.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/junit/src/org/netbeans/modules/junit/output/NodeStateUtilities.java Fri Aug 29 11:34:17 2008 +0200 @@ -0,0 +1,189 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2008 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.junit.output; + +import java.util.BitSet; +import org.openide.explorer.view.TreeView; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + +/** + * Utility class containing methods for storage and recovery of nodes' + * expansion states (collapsed/expanded). + * + * @author Marian Petras + */ +final class NodeStateUtilities { + + private NodeStateUtilities() { } + + /** + */ + static Object getExpansionState(final Node node, + final TreeView treeView) { + if (!treeView.isExpanded(node)) { + return FALSE; + } + + return getExpansionStates(node.getChildren(), treeView); + } + + /** + */ + static void restoreExpansionState(final Node node, + final Object stateInfo, + final TreeView treeView) { + if (stateInfo == FALSE) { + //we will not be collapsing nodes expanded by the user + } else if (stateInfo != null) { + treeView.expandNode(node); + if (stateInfo != TRUE) { + restoreExpansionStates(node.getChildren(), stateInfo, treeView); + } + } + } + + /** + */ + static Object getExpansionStates(final Children children, + final TreeView treeView) { + if (children == Children.LEAF) { + return FALSE; + } + + return getExpansionStates(children.getNodes(), treeView); + } + + /** + */ + static void restoreExpansionStates(final Children children, + final Object statesInfo, + final TreeView treeView) { + if (children == Children.LEAF) { + return; + } + + restoreExpansionStates(children.getNodes(true), statesInfo, treeView); + } + + /** + */ + static Object getExpansionStates(final Node[] nodes, + final TreeView treeView) { + if (nodes.length == 0) { + return TRUE; + } + + BitSet stateSet = null; + Object[] stateArray = null; + for (int i = 0; i < nodes.length; i++) { + Object expansionState = getExpansionState(nodes[i], treeView); + if (stateArray == null) { + if (expansionState == TRUE) { + if (stateSet == null) { + stateSet = new BitSet(nodes.length); + } + stateSet.set(i); + continue; + } + + if (expansionState == FALSE) { + //stateSet.clear(i); //it is the default value + continue; + } + + /* + * Oops! Something else then TRUE or FALSE! + * We cannot store such a value in a bitset. + * So convert the data collected so far to another format + * - to an array of objects: + */ + stateArray = new Object[nodes.length]; + for (int j = 0; j < i; j++) { + stateArray[j] = stateSet.get(j) ? TRUE : FALSE; + } + stateSet = null; + } + stateArray[i] = expansionState; + } + assert (stateSet == null) || (stateArray == null); //at most one is used + + if ((stateSet == null) && (stateArray == null)) { + /* no node expanded */ + return TRUE; + } + + return (stateSet != null) ? stateSet : stateArray; + } + + /** + */ + static void restoreExpansionStates(final Node[] nodes, + final Object statesInfo, + final TreeView treeView) { + if (statesInfo == null) { + return; + } + + final Class infoClass = statesInfo.getClass(); + if (infoClass == Boolean.class) { + assert ((Boolean) statesInfo).booleanValue(); //always TRUE + //nothing to do (nothing to expand) + } else if (infoClass == BitSet.class) { + BitSet stateSet = (BitSet) statesInfo; + int length = Math.min(stateSet.size(), nodes.length); + for (int i = stateSet.nextSetBit(0); + (i < length) && (i != -1); + i = stateSet.nextSetBit(i + 1)) { + treeView.expandNode(nodes[i]); + } + } else { + assert infoClass.isArray(); + Object[] states = (Object[]) statesInfo; + int length = Math.min(nodes.length, states.length); + for (int i = 0; i < length; i++) { + restoreExpansionState(nodes[i], states[i], treeView); + } + } + } + +} diff -r f080832b3afd junit/src/org/netbeans/modules/junit/output/ResultPanelTree.java --- a/junit/src/org/netbeans/modules/junit/output/ResultPanelTree.java Thu Aug 28 22:00:57 2008 +0200 +++ b/junit/src/org/netbeans/modules/junit/output/ResultPanelTree.java Fri Aug 29 11:34:17 2008 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common @@ -24,7 +24,7 @@ * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun * Microsystems, Inc. All Rights Reserved. * * If you wish your version of this file to be governed by only the CDDL @@ -222,7 +222,7 @@ this.filtered = filtered; - rootNode.setFiltered(filtered); + rootNode.setFiltered(filtered, treeView); } /** diff -r f080832b3afd junit/src/org/netbeans/modules/junit/output/RootNode.java --- a/junit/src/org/netbeans/modules/junit/output/RootNode.java Thu Aug 28 22:00:57 2008 +0200 +++ b/junit/src/org/netbeans/modules/junit/output/RootNode.java Fri Aug 29 11:34:17 2008 +0200 @@ -43,6 +43,7 @@ import java.awt.EventQueue; import java.util.Collection; +import org.openide.explorer.view.TreeView; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.util.NbBundle; @@ -172,7 +173,7 @@ /** */ - void setFiltered(final boolean filtered) { + void setFiltered(final boolean filtered, final TreeView treeView) { assert EventQueue.isDispatchThread(); if (filtered == this.filtered) { @@ -182,7 +183,7 @@ Children children = getChildren(); if (children != Children.LEAF) { - ((RootNodeChildren) children).setFiltered(filtered); + ((RootNodeChildren) children).setFiltered(filtered, treeView); } } diff -r f080832b3afd junit/src/org/netbeans/modules/junit/output/RootNodeChildren.java --- a/junit/src/org/netbeans/modules/junit/output/RootNodeChildren.java Thu Aug 28 22:00:57 2008 +0200 +++ b/junit/src/org/netbeans/modules/junit/output/RootNodeChildren.java Fri Aug 29 11:34:17 2008 +0200 @@ -46,6 +46,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import org.openide.explorer.view.TreeView; import org.openide.nodes.Children; import org.openide.nodes.Node; @@ -69,6 +70,8 @@ private String runningSuiteName; /** */ private TestsuiteNode runningSuiteNode; + /** */ + private Object nodeStateInfo; /** * Creates a new instance of ReportRootNode @@ -233,7 +236,7 @@ super.removeNotify(); live = false; } - + /** * Adds all nodes matching the current filter (if the filter is enabled) * or all nodes generally (if the filter is off). @@ -267,7 +270,7 @@ private void removeAllNodes() { remove(getNodes()); } - + /** */ private TestsuiteNode createNode(final Report report) { @@ -276,7 +279,8 @@ /** */ - void setFiltered(final boolean filtered) { + void setFiltered(final boolean filtered, + final TreeView treeView) { assert EventQueue.isDispatchThread(); if (filtered == this.filtered) { @@ -289,10 +293,24 @@ } if (filtered) { + storeNodeExpansionState(treeView); removePassedSuites(); } else { addPassedSuites(); + recallNodeExpansionState(treeView); } + } + + private void storeNodeExpansionState(final TreeView treeView) { + assert nodeStateInfo == null; + nodeStateInfo = NodeStateUtilities.getExpansionStates(this, treeView); + } + + private void recallNodeExpansionState(final TreeView treeView) { + if ((nodeStateInfo != null) && (nodeStateInfo.getClass() != Boolean.class)) { + NodeStateUtilities.restoreExpansionStates(this, nodeStateInfo, treeView); + } + nodeStateInfo = null; } /**