/*
* Copyright 2006,2007 Enrico Boldrini, Lorenzo Bigagli This file is part of
* CheckboxTree. CheckboxTree is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. CheckboxTree is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with CheckboxTree; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
*/
package net.sourceforge.pmd.jedit.checkboxtree;
import javax.swing.tree.TreePath;
/**
* PropagatePreservingUncheckTreeCheckingMode define a TreeCheckingMode with
* down and up recursion of the check when nodes are clicked. It propagates the
* change not only to descendants but also to ancestors. With regard to
* descendants this mode behaves exactly like the Propagate mode. With regard to
* ancestors it checks/unchecks them as needed so that a node is unchecked if
* and only if all of its children are unchecked.
*
* @author Boldrini
*/
public class PropagatePreservingUncheckTreeCheckingMode extends TreeCheckingMode {
PropagatePreservingUncheckTreeCheckingMode(DefaultTreeCheckingModel model) {
super(model);
}
@Override
public void checkPath(TreePath path) {
// check is propagated to children
this.model.checkSubTree(path);
// check all the ancestors with subtrees checked
TreePath[] parents = new TreePath[path.getPathCount()];
parents[0] = path;
// boolean uncheckAll = false;
boolean greyAll = false;
for (int i = 1; i < parents.length; i++) {
parents[i] = parents[i - 1].getParentPath();
this.model.addToCheckedPathsSet(parents[i]);
if (greyAll) {
this.model.addToGreyedPathsSet(parents[i]);
} else {
switch (this.model.getChildrenChecking(parents[i])) {
case HALF_CHECKED:
this.model.addToGreyedPathsSet(parents[i]);
greyAll = true;
break;
case ALL_UNCHECKED:
System.err.println("This should not happen (PropagatePreservingUncheckTreeCheckingMode)");
break;
case ALL_CHECKED:
this.model.removeFromGreyedPathsSet(parents[i]);
break;
default:
case NO_CHILDREN:
System.err.println("This should not happen (PropagatePreservingCheckTreeCheckingMode)");
break;
}
}
}
}
@Override
public void uncheckPath(TreePath path) {
// uncheck is propagated to children
this.model.uncheckSubTree(path);
TreePath parentPath = path;
// check all the ancestors with subtrees checked
while ((parentPath = parentPath.getParentPath()) != null) {
switch (this.model.getChildrenChecking(parentPath)) {
case HALF_CHECKED:
this.model.addToCheckedPathsSet(parentPath);
this.model.addToGreyedPathsSet(parentPath);
break;
case ALL_UNCHECKED:
this.model.removeFromCheckedPathsSet(parentPath);
this.model.removeFromGreyedPathsSet(parentPath);
break;
case ALL_CHECKED:
System.err.println("This should not happen (PropagatePreservingUncheckTreeCheckingMode)");
break;
default:
case NO_CHILDREN:
System.err.println("This should not happen (PropagatePreservingCheckTreeCheckingMode)");
break;
}
}
}
/*
* (non-Javadoc)
*
* @see net.sourceforge.pmd.jedit.checkboxtree.TreeCheckingMode#updateCheckAfterChildrenInserted(javax.swing.tree.TreePath)
*/
@Override
public void updateCheckAfterChildrenInserted(TreePath parent) {
if (this.model.isPathChecked(parent)) {
this.model.checkSubTree(parent);
} else {
this.model.uncheckSubTree(parent);
}
}
/*
* (non-Javadoc)
*
* @see net.sourceforge.pmd.jedit.checkboxtree.TreeCheckingMode#updateCheckAfterChildrenRemoved(javax.swing.tree.TreePath)
*/
@Override
public void updateCheckAfterChildrenRemoved(TreePath parent) {
if (this.model.isPathChecked(parent)) {
// System.out.println(parent +" was removed (not checked)");
if (this.model.getChildrenPath(parent).length != 0) {
if (!this.model.pathHasChildrenWithValue(parent, true)) {
// System.out.println("uncheking it");
uncheckPath(parent);
}
}
}
this.model.updatePathGreyness(parent);
this.model.updateAncestorsGreyness(parent);
}
/*
* (non-Javadoc)
*
* @see net.sourceforge.pmd.jedit.checkboxtree.TreeCheckingMode#updateCheckAfterStructureChanged(javax.swing.tree.TreePath)
*/
@Override
public void updateCheckAfterStructureChanged(TreePath parent) {
if (this.model.isPathChecked(parent)) {
checkPath(parent);
} else {
uncheckPath(parent);
}
}
}