diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/ContainerCheckedTreeViewer.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/ContainerCheckedTreeViewer.java index 820a26e..f3e6161 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/ContainerCheckedTreeViewer.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/ContainerCheckedTreeViewer.java @@ -15,8 +15,8 @@ package org.eclipse.ui.dialogs; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; +import java.util.Set; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ITreeViewerListener; import org.eclipse.jface.viewers.TreeExpansionEvent; @@ -209,27 +209,45 @@ @Override public void setCheckedElements(Object[] elements) { Object[] oldCheckedElements = getCheckedElements(); - super.setCheckedElements(elements); + Set elementsToCheck = new HashSet<>(); + Set elementsToUncheck = getSetOf(oldCheckedElements); + for (Object element : elements) { + if (!elementsToUncheck.remove(element)) { + elementsToCheck.add(element); + } + } + + if (elementsToCheck.isEmpty() && elementsToUncheck.isEmpty()) { + return; // noting changed + } + + elementsToCheck.forEach(element -> super.setChecked(element, true)); + elementsToUncheck.forEach(element -> super.setChecked(element, false)); Control tree = getControl(); try { tree.setRedraw(false); - if (oldCheckedElements.length > 0) { - // calculate intersection of previously and newly checked elements to avoid - // no-op updates - HashSet changedElements = new HashSet<>(Arrays.asList(elements)); - for (Object element : oldCheckedElements) { - changedElements.remove(element); - } - doCheckStateChanged(changedElements.toArray()); - } else { - doCheckStateChanged(elements); + if (!elementsToCheck.isEmpty()) { + doCheckStateChanged(elementsToCheck.toArray()); + } + + if (!elementsToUncheck.isEmpty()) { + updateElementsState(elementsToUncheck); } } finally { tree.setRedraw(true); } } + private void updateElementsState(Set elementsToUpdate) { + for (Object element : elementsToUpdate) { + Widget item = findItem(element); + if (item instanceof TreeItem) { + updateParentItems((TreeItem) item); + } + } + } + @Override public boolean setSubtreeChecked(Object element, boolean state) { if (super.setSubtreeChecked(element, state)) { @@ -281,4 +299,12 @@ } } + private Set getSetOf(Object[] objects) { + Set set = new HashSet<>(objects.length); + for (Object o : objects) { + set.add(o); + } + + return set; + } }