package jetbrains.mps.debugger.api.ui.breakpoints; /*Generated by MPS */ import jetbrains.mps.ide.platform.ui.CheckBoxNodeRenderer; import jetbrains.mps.ide.ui.tree.MPSTree; import jetbrains.mps.ide.ui.tree.MPSTreeNode; import java.util.Collection; import org.jetbrains.annotations.Nullable; import javax.swing.Icon; import org.jetbrains.annotations.NotNull; import java.util.Map; import java.util.Set; import java.util.HashMap; import java.util.HashSet; import java.awt.Color; import javax.swing.UIManager; /*package*/ abstract class GroupedTree<D extends CheckBoxNodeRenderer.NodeData> extends MPSTree { public GroupedTree() { setCellRenderer(new CheckBoxNodeRenderer(true)); setCellEditor(new CheckBoxNodeRenderer.CheckBoxNodeEditor<CheckBoxNodeRenderer.NodeData>(true) { @Override protected CheckBoxNodeRenderer.NodeData createNodeData(boolean selected) { CheckBoxNodeRenderer.NodeData data = getObject(); data.setSelected(selected); repaint(); return data; } }); setEditable(true); } protected abstract MPSTreeNode createDataNode(D data); protected abstract GroupedTree.GroupKind<D, Object> createRootGroupKind(); protected abstract Collection<D> getData(); @Override protected MPSTreeNode rebuild() { return new GroupedTree.GroupTreeNode(createRootGroupKind(), new Object(), getData()); } @Nullable public MPSTreeNode findNodeForData(D nodeData) { if (this.isEmpty()) { return null; } return findNodeForData((GroupedTree.GroupTreeNode) getRootNode(), nodeData); } @Nullable private MPSTreeNode findNodeForData(GroupedTree.GroupTreeNode rootNode, D nodeData) { for (int i = 0; i < rootNode.getChildCount(); i++) { MPSTreeNode child = (MPSTreeNode) rootNode.getChildAt(i); if (child instanceof GroupedTree.GroupTreeNode) { GroupedTree.GroupData groupData = ((GroupedTree.GroupTreeNode) child).getGroupData(); if (groupData.getKind().getGroup(nodeData).equals(groupData.getGroup())) { return findNodeForData((GroupedTree.GroupTreeNode) child, nodeData); } } else if (child.getUserObject() != null && child.getUserObject().equals(nodeData)) { return child; } } return null; } public static abstract class GroupKind<D, T> { private boolean myIsVisible = true; public GroupKind() { } @Nullable public abstract T getGroup(D data); @Nullable public Icon getIcon(T group) { return null; } public String getText(@NotNull T group) { return group.toString(); } @Nullable public GroupedTree.GroupKind getSubGroupKind() { return null; } public Map<T, Set<D>> sortByGroups(Collection<D> dataToSort) { Map<T, Set<D>> result = new HashMap<T, Set<D>>(); for (D data : dataToSort) { T group = getGroup(data); Set<D> dataForGroup = result.get(group); if (dataForGroup == null) { dataForGroup = new HashSet<D>(); result.put(group, dataForGroup); } dataForGroup.add(data); } return result; } public boolean isVisible() { return myIsVisible; } public void setVisible(boolean isVisible) { myIsVisible = isVisible; } } private class GroupData<D extends CheckBoxNodeRenderer.NodeData, T> implements CheckBoxNodeRenderer.NodeData { @NotNull private final GroupedTree.GroupKind<D, T> myKind; @NotNull private final T myGroup; private final Collection<D> myData; public GroupData(T group, GroupedTree.GroupKind<D, T> kind, Collection<D> data) { myGroup = group; myKind = kind; myData = data; } @Override public Icon getIcon(boolean expanded) { return myKind.getIcon(myGroup); } @Override public Color getColor() { return UIManager.getColor("Tree.textForeground"); } @Override public String getText() { return myKind.getText(myGroup); } @Override public boolean isSelected() { for (D d : myData) { if (!(d.isSelected())) { return false; } } return true; } @NotNull public GroupedTree.GroupKind<D, T> getKind() { return myKind; } @NotNull public T getGroup() { return myGroup; } @Override public void setSelected(boolean selected) { for (D d : myData) { d.setSelected(selected); } } } private class GroupTreeNode<T> extends MPSTreeNode { private final Collection<D> myData; public GroupTreeNode(@NotNull GroupedTree.GroupKind<D, T> kind, @NotNull T group, Collection<D> data) { super(new GroupedTree.GroupData(group, kind, data)); GroupedTree.GroupData groupData = getGroupData(); setNodeIdentifier(groupData.getText()); setText(groupData.getText()); Icon icon = groupData.getIcon(false); if (icon != null) { setIcon(icon); } myData = data; GroupedTree.GroupKind<D, Object> subGroupKind = kind.getSubGroupKind(); while (subGroupKind != null && !(subGroupKind.isVisible())) { subGroupKind = subGroupKind.getSubGroupKind(); } if (subGroupKind == null) { for (D d : myData) { add(createDataNode(d)); } } else { Map<Object, Set<D>> sorted = subGroupKind.sortByGroups(myData); for (Object subGroup : sorted.keySet()) { if (subGroup != null) { add(new GroupedTree.GroupTreeNode(subGroupKind, subGroup, sorted.get(subGroup))); } else { for (D d : sorted.get(subGroup)) { add(createDataNode(d)); } } } } } private GroupedTree.GroupData getGroupData() { return (GroupedTree.GroupData) getUserObject(); } } }