private ActionCallback processAjusted( final Map<Object, Condition> adjusted, final Set<Object> originallySelected) { final ActionCallback result = new ActionCallback(); final Set<Object> allSelected = myUi.getSelectedElements(); Set<Object> toSelect = new HashSet<Object>(); for (Map.Entry<Object, Condition> entry : adjusted.entrySet()) { if (entry.getValue().value(entry.getKey())) continue; for (final Object eachSelected : allSelected) { if (isParentOrSame(entry.getKey(), eachSelected)) continue; toSelect.add(entry.getKey()); } if (allSelected.isEmpty()) { toSelect.add(entry.getKey()); } } final Object[] newSelection = ArrayUtil.toObjectArray(toSelect); if (newSelection.length > 0) { myUi._select( newSelection, new Runnable() { @Override public void run() { final Set<Object> hangByParent = new HashSet<Object>(); processUnsuccessfulSelections( newSelection, new Function<Object, Object>() { @Override public Object fun(final Object o) { if (myUi.isInStructure(o) && !adjusted.get(o).value(o)) { hangByParent.add(o); } else { addAdjustedSelection(o, adjusted.get(o), null); } return null; } }, originallySelected); processHangByParent(hangByParent).notify(result); } }, false, true, true); } else { result.setDone(); } return result; }
private boolean isParentOrSame(Object parent, Object child) { Object eachParent = child; while (eachParent != null) { if (parent.equals(eachParent)) return true; eachParent = myUi.getTreeStructure().getParentElement(eachParent); } return false; }
public void setProcessingNow(boolean processingNow) { if (processingNow) { myProcessingCount++; } else { myProcessingCount--; } if (!isProcessingNow()) { myUi.maybeReady(); } }
private void processNextHang(Object element, final ActionCallback callback) { if (element == null || myUi.getSelectedElements().contains(element)) { callback.setDone(); } else { final Object nextElement = myUi.getTreeStructure().getParentElement(element); if (nextElement == null) { callback.setDone(); } else { myUi.select( nextElement, new Runnable() { public void run() { processNextHang(nextElement, callback); } }, true); } } }
public UpdaterTreeState(AbstractTreeUi ui, boolean isEmpty) { myUi = ui; if (!isEmpty) { final JTree tree = myUi.getTree(); putAll(addPaths(tree.getSelectionPaths()), myToSelect); putAll( addPaths(tree.getExpandedDescendants(new TreePath(tree.getModel().getRoot()))), myToExpand); } }
private void invalidateToSelectWithRefsToParent(DefaultMutableTreeNode actionNode) { if (actionNode != null) { Object readyElement = myUi.getElementFor(actionNode); if (readyElement != null) { Iterator<Object> toSelect = myToSelect.keySet().iterator(); while (toSelect.hasNext()) { Object eachToSelect = toSelect.next(); if (readyElement.equals(myUi.getTreeStructure().getParentElement(eachToSelect))) { List<Object> children = myUi.getLoadedChildrenFor(readyElement); if (!children.contains(eachToSelect)) { toSelect.remove(); if (!myToSelect.containsKey(readyElement) && !myUi.getSelectedElements().contains(eachToSelect)) { addAdjustedSelection(eachToSelect, Conditions.alwaysFalse(), null); } } } } } } }
private Set<Object> addPaths(Collection elements) { Set<Object> target = new HashSet<Object>(); if (elements != null) { for (Object each : elements) { final Object node = ((TreePath) each).getLastPathComponent(); if (node instanceof DefaultMutableTreeNode) { final Object descriptor = ((DefaultMutableTreeNode) node).getUserObject(); if (descriptor instanceof NodeDescriptor) { final Object element = myUi.getElementFromDescriptor((NodeDescriptor) descriptor); if (element != null) { target.add(element); } } } } } return target; }
private void processUnsuccessfulSelections( final Object[] toSelect, Function<Object, Object> restore, Set<Object> originallySelected) { final Set<Object> selected = myUi.getSelectedElements(); boolean wasFullyRejected = false; if (toSelect.length > 0 && !selected.isEmpty() && !originallySelected.containsAll(selected)) { final Set<Object> successfulSelections = new HashSet<Object>(); ContainerUtil.addAll(successfulSelections, toSelect); successfulSelections.retainAll(selected); wasFullyRejected = successfulSelections.isEmpty(); } else if (selected.isEmpty() && originallySelected.isEmpty()) { wasFullyRejected = true; } if (wasFullyRejected && !selected.isEmpty()) return; for (Object eachToSelect : toSelect) { if (!selected.contains(eachToSelect)) { restore.fun(eachToSelect); } } }
public boolean restore(@Nullable DefaultMutableTreeNode actionNode) { if (isProcessingNow() || !myCanRunRestore || myUi.hasNodesToUpdate()) { return false; } invalidateToSelectWithRefsToParent(actionNode); setProcessingNow(true); final Object[] toSelect = getToSelect(); final Object[] toExpand = getToExpand(); final Map<Object, Condition> adjusted = new WeakHashMap<Object, Condition>(); adjusted.putAll(myAdjustedSelection); clearSelection(); clearExpansion(); final Set<Object> originallySelected = myUi.getSelectedElements(); myUi._select( toSelect, new Runnable() { @Override public void run() { processUnsuccessfulSelections( toSelect, new Function<Object, Object>() { @Override public Object fun(final Object o) { if (myUi.getTree().isRootVisible() || !myUi.getTreeStructure().getRootElement().equals(o)) { addSelection(o); } return o; } }, originallySelected); processAjusted(adjusted, originallySelected) .doWhenDone( new Runnable() { @Override public void run() { myUi.expand( toExpand, new Runnable() { @Override public void run() { myUi.clearUpdaterState(); setProcessingNow(false); } }, true); } }); } }, false, true, true, false); return true; }