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();
}
}
}